package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import org.apache.jasper.runtime.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.Cookie;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.lang.Math;

public class ga_jsp extends HttpJspBase {


/*java.util.UUID no import*/
/**
  Copyright 2009 Google Inc. All Rights Reserved.
**/

  // Tracker version.
  private static final String version = "4.4sj";

  private static final String COOKIE_NAME = "__utmmobile";

  // The path the cookie will be available to, edit this to use a different
  // cookie path.
  private static final String COOKIE_PATH = "/";

  // Two years in seconds.
  private static final int COOKIE_USER_PERSISTENCE = 63072000;

  // 1x1 transparent GIF
  private static final byte[] GIF_DATA = new byte[] {
      (byte)0x47, (byte)0x49, (byte)0x46, (byte)0x38, (byte)0x39, (byte)0x61,
      (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x80, (byte)0xff,
      (byte)0x00, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0x00, (byte)0x00,
      (byte)0x00, (byte)0x2c, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
      (byte)0x01, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x00, (byte)0x02,
      (byte)0x02, (byte)0x44, (byte)0x01, (byte)0x00, (byte)0x3b
  };

  // A string is empty in our terms, if it is null, empty or a dash.
  private static boolean isEmpty(String in) {
    return in == null || "-".equals(in) || "".equals(in);
  }

  // The last octect of the IP address is removed to anonymize the user.
  private static String getIP(String remoteAddress) {
    if (isEmpty(remoteAddress)) {
      return "";
    }
    // Capture the first three octects of the IP address and replace the forth
    // with 0, e.g. 124.455.3.123 becomes 124.455.3.0
    String regex = "^([^.]+\\.[^.]+\\.[^.]+\\.).*";
    Pattern getFirstBitOfIPAddress = Pattern.compile(regex);
    Matcher m = getFirstBitOfIPAddress.matcher(remoteAddress);
    if (m.matches()) {
      return m.group(1) + "0";
    } else {
      return "";
    }
  }

  // Generate a visitor id for this hit.
  // If there is a visitor id in the cookie, use that, otherwise
  // use the guid if we have one, otherwise use a random number.
  private static String getVisitorId(
      String guid, String account, String userAgent, Cookie cookie)
      throws NoSuchAlgorithmException, UnsupportedEncodingException {

    // If there is a value in the cookie, don't change it.
    if (cookie != null && cookie.getValue() != null) {
      return cookie.getValue();
    }

    String message;
    if (!isEmpty(guid)) {
      // Create the visitor id using the guid.
      message = guid + account;
    } else {
      // otherwise this is a new user, create a new random id.
      //message = userAgent + getRandomNumber() + UUID.randomUUID().toString();
      StringBuffer UUID = new StringBuffer();
      String hex = "";
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      UUID.append("-");
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      UUID.append("-");
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      UUID.append("-");
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      UUID.append("-");
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      hex = Integer.toHexString((int)(65535*Math.random()));
      while (hex.length()<4) hex="0"+hex;
      UUID.append(hex);
      message = userAgent + getRandomNumber() + UUID.toString();
    }

    MessageDigest m = MessageDigest.getInstance("MD5");
    m.update(message.getBytes("UTF-8"), 0, message.length());
    byte[] sum = m.digest();
    BigInteger messageAsNumber = new BigInteger(1, sum);
    String md5String = messageAsNumber.toString(16);

    // Pad to make sure id is 32 characters long.
    while (md5String.length() < 32) {
      md5String = "0" + md5String;
    }

    return "0x" + md5String.substring(0, 16);
  }

  // Get a random number string.
  private static String getRandomNumber() {
    return Integer.toString((int) (Math.random() * 0x7fffffff));
  }

  // Writes the bytes of a 1x1 transparent gif into the response.
  private void writeGifData(HttpServletResponse response) throws IOException {
    response.addHeader(
        "Cache-Control",
        "private, no-cache, no-cache=Set-Cookie, proxy-revalidate");
    response.addHeader("Pragma", "no-cache");
    response.addHeader("Expires", "Wed, 17 Sep 1975 21:32:10 GMT");
    ServletOutputStream output = response.getOutputStream();
    output.write(GIF_DATA);
    output.flush();
  }

  // Make a tracking request to Google Analytics from this server.
  // Copies the headers from the original request to the new one.
  // If request containg utmdebug parameter, exceptions encountered
  // communicating with Google Analytics are thown.
  private void sendRequestToGoogleAnalytics(
      String utmUrl, HttpServletRequest request) throws Exception {
    try {
      URL url = new URL(utmUrl);
      URLConnection connection = url.openConnection();
      connection.setUseCaches(false);

      connection.addRequestProperty("User-Agent",
          request.getHeader("User-Agent"));
      connection.addRequestProperty("Accepts-Language",
          request.getHeader("Accepts-Language"));

      connection.getContent();
    } catch (Exception e) {
      if (request.getParameter("utmdebug") != null) {
        throw new Exception(e);
      }
    }
  }

  // Track a page view, updates all the cookies and campaign tracker,
  // makes a server side request to Google Analytics and writes the transparent
  // gif byte data to the response.
  private void trackPageView(
      HttpServletRequest request, HttpServletResponse response)
      throws Exception {
    String timeStamp = Long.toString(System.currentTimeMillis() / 1000);
    String domainName = request.getServerName();
    if (isEmpty(domainName)) {
      domainName = "";
    }

    // Get the referrer from the utmr parameter, this is the referrer to the
    // page that contains the tracking pixel, not the referrer for tracking
    // pixel.
    String documentReferer = request.getParameter("utmr");
    if (isEmpty(documentReferer)) {
      documentReferer = "-";
    } else {
      documentReferer = URLDecoder.decode(documentReferer, "UTF-8");
    }
    String documentPath = request.getParameter("utmp");
    if (isEmpty(documentPath)) {
      documentPath = "";
    } else {
      documentPath = URLDecoder.decode(documentPath, "UTF-8");
    }

    String account = request.getParameter("utmac");
    String userAgent = request.getHeader("User-Agent");
    if (isEmpty(userAgent)) {
      userAgent = "";
    }

    // Try and get visitor cookie from the request.
    Cookie[] cookies = request.getCookies();
    Cookie cookie = null;
    if (cookies != null) {
      for(int i = 0; i < cookies.length; i++) {
        if (cookies[i].getName().equals(COOKIE_NAME)) {
          cookie = cookies[i];
        }
      }
    }

    String guidHeader = request.getHeader("X-DCMGUID");
    if (isEmpty(guidHeader)) {
      guidHeader = request.getHeader("X-UP-SUBNO");
    }
    if (isEmpty(guidHeader)) {
      guidHeader = request.getHeader("X-JPHONE-UID");
    }
    if (isEmpty(guidHeader)) {
      guidHeader = request.getHeader("X-EM-UID");
    }

    String visitorId = getVisitorId(guidHeader, account, userAgent, cookie);

    // Always try and add the cookie to the response.
    Cookie newCookie = new Cookie(COOKIE_NAME, visitorId);
    newCookie.setMaxAge(COOKIE_USER_PERSISTENCE);
    newCookie.setPath(COOKIE_PATH);
    response.addCookie(newCookie);

    String utmGifLocation = "http://www.google-analytics.com/__utm.gif";

    // Construct the gif hit url.
    String utmUrl = utmGifLocation + "?" +
        "utmwv=" + version +
        "&utmn=" + getRandomNumber() +
        "&utmhn=" + URLEncoder.encode(domainName, "UTF-8") +
        "&utmr=" + URLEncoder.encode(documentReferer, "UTF-8") +
        "&utmp=" + URLEncoder.encode(documentPath, "UTF-8") +
        "&utmac=" + account +
        "&utmcc=__utma%3D999.999.999.999.999.1%3B" +
        "&utmvid=" + visitorId +
        "&utmip=" + getIP(request.getRemoteAddr());

    sendRequestToGoogleAnalytics(utmUrl, request);

    // If the debug parameter is on, add a header to the response that contains
    // the url that was used to contact Google Analytics.
    if (request.getParameter("utmdebug") != null) {
      response.setHeader("X-GA-MOBILE-URL", utmUrl);
    }
    // Finally write the gif data to the response.
    writeGifData(response);
  }


  private static java.util.Vector _jspx_includes;

  public java.util.List getIncludes() {
    return _jspx_includes;
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    JspFactory _jspxFactory = null;
    javax.servlet.jsp.PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;


    try {
      _jspxFactory = JspFactory.getDefaultFactory();
      response.setContentType("image/gif;charset=ISO-8859-1");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;


  // Let exceptions bubble up to container, for better debugging.
  trackPageView(request, response);

    } catch (Throwable t) {
      out = _jspx_out;
      if (out != null && out.getBufferSize() != 0)
        out.clearBuffer();
      if (pageContext != null) pageContext.handlePageException(t);
    } finally {
      if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext);
    }
  }
}
