/*
 * Copyright 2006 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package com.google.gwt.dev.shell;

import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.HelpInfo;
import com.google.gwt.dev.About;
import com.google.gwt.dev.GwtVersion;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.prefs.Preferences;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

/**
 * Orchestrates a best-effort attempt to find out if a new version of GWT is
 * available.
 */
public final class CheckForUpdates {

  /**
   * Returns the result of an update check.
   */
  public interface UpdateResult {
    /**
     * @return the new version of GWT available.
     */
    GwtVersion getNewVersion();

    /**
     * @return the URL for details about the new version.
     */
    URL getURL();
  }

  public static final long ONE_DAY = 24 * 60 * 60 * 1000;
  public static final long ONE_MINUTE = 60 * 1000;

  // System properties used by CheckForUpdates
  protected static final String PROPERTY_DEBUG_HTTP_GET = "gwt.debugLowLevelHttpGet";
  protected static final String PROPERTY_PREFS_NAME = "gwt.prefsPathName";
  protected static final String PROPERTY_QUERY_URL = "gwt.forceVersionCheckURL";

  // Log levels -- in general we want the logging of the update process
  // to not be visible to normal users.
  private static final TreeLogger.Type CHECK_ERROR = TreeLogger.DEBUG;
  private static final TreeLogger.Type CHECK_INFO = TreeLogger.SPAM;
  private static final TreeLogger.Type CHECK_SPAM = TreeLogger.SPAM;
  private static final TreeLogger.Type CHECK_WARN = TreeLogger.SPAM;

  // Preferences keys
  private static final String FIRST_LAUNCH = "firstLaunch";
  private static final String HIGHEST_RUN_VERSION = "highestRunVersion";
  private static final String LAST_PING = "lastPing";
  private static final String NEXT_PING = "nextPing";

  // Uncomment one of constants below to try different variations of failure to
  // make sure we never interfere with the app running.

  // Check against a fake server to see failure to contact server.
  // protected static final String QUERY_URL =
  // "http://nonexistenthost:1111/gwt/currentversion.xml";

  // Check 404 on a real location that doesn't have the file.
  // protected static final String QUERY_URL =
  // "http://www.google.com/gwt/currentversion.xml";

  // A test URL for seeing it actually work in a sandbox.
  // protected static final String QUERY_URL =
  // "http://localhost/gwt/currentversion.xml";

  // The real URL that should be used.
  private static final String QUERY_URL = "http://tools.google.com/webtoolkit/currentversion.xml";

  public static FutureTask<UpdateResult> checkForUpdatesInBackgroundThread(
      final TreeLogger logger, final long minCheckMillis) {
    final String entryPoint = computeEntryPoint();
    FutureTask<UpdateResult> task = new FutureTask<UpdateResult>(
        new Callable<UpdateResult>() {
          @Override
          public UpdateResult call() throws Exception {
            final CheckForUpdates updateChecker = createUpdateChecker(logger,
                entryPoint);
            return updateChecker == null ? null
                : updateChecker.check(minCheckMillis);
          }
        });
    Thread checkerThread = new Thread(task, "GWT Update Checker");
    checkerThread.setDaemon(true);
    checkerThread.start();
    return task;
  }

  /**
   * Find the first method named "main" on the call stack and use its class as
   * the entry point.
   */
  public static String computeEntryPoint() {
    Throwable t = new Throwable();
    for (StackTraceElement stackTrace : t.getStackTrace()) {
      if (stackTrace.getMethodName().equals("main")) {
        // Strip package name from main's class
        String className = stackTrace.getClassName();
        int i = className.lastIndexOf('.');
        if (i >= 0) {
          return className.substring(i + 1);
        }
        return className;
      }
    }
    return null;
  }

  public static CheckForUpdates createUpdateChecker(TreeLogger logger) {
    return createUpdateChecker(logger, computeEntryPoint());
  }

  public static CheckForUpdates createUpdateChecker(TreeLogger logger,
      String entryPoint) {
    return new CheckForUpdates(logger, entryPoint);
  }

  public static void logUpdateAvailable(TreeLogger logger,
      FutureTask<UpdateResult> updater) {
    if (updater != null && updater.isDone()) {
      UpdateResult result = null;
      try {
        result = updater.get(0, TimeUnit.MILLISECONDS);
      } catch (InterruptedException e) {
        // Silently ignore exception
      } catch (ExecutionException e) {
        // Silently ignore exception
      } catch (TimeoutException e) {
        // Silently ignore exception
      }
      logUpdateAvailable(logger, result);
    }
  }

  public static void logUpdateAvailable(TreeLogger logger,
      UpdateResult result) {
    if (result != null) {
      final URL url = result.getURL();
      logger.log(TreeLogger.WARN, "A new version of GWT ("
          + result.getNewVersion() + ") is available", null, new HelpInfo() {
            @Override
            public String getAnchorText() {
              return "Release Notes";
            }

            @Override
            public URL getURL() {
              return url;
            }
          });
    }
  }

  private static String getTextOfLastElementHavingTag(Document doc,
      String tagName) {
    NodeList nodeList = doc.getElementsByTagName(tagName);
    int n = nodeList.getLength();
    if (n > 0) {
      Element elem = (Element) nodeList.item(n - 1);
      // Assume the first child is the value.
      //
      Node firstChild = elem.getFirstChild();
      if (firstChild != null) {
        String text = firstChild.getNodeValue();
        return text;
      }
    }

    return null;
  }

  private String entryPoint;

  private TreeLogger logger;

  private GwtVersion myVersion;

  /**
   * Create an update checker which will poll a server URL and log a message
   * about an update if available.
   *
   * @param logger TreeLogger to use
   * @param entryPoint the name of the main entry point used for this execution
   */
  public CheckForUpdates(TreeLogger logger, String entryPoint) {
    this.logger = logger;
    this.entryPoint = entryPoint;
    myVersion = About.getGwtVersionObject();
  }

  /**
   * Check for updates and log to the logger if they are available.
   *
   * @return an UpdateResult or null if there is no new update
   */
  public UpdateResult check(long minCheckMillis) {
    TreeLogger branch = logger.branch(CHECK_INFO, "Checking for updates");
    try {
      String prefsName = System.getProperty(PROPERTY_PREFS_NAME);
      Preferences prefs;
      if (prefsName != null) {
        prefs = Preferences.userRoot().node(prefsName);
      } else {
        prefs = Preferences.userNodeForPackage(CheckForUpdates.class);
      }

      String queryURL = QUERY_URL;
      String forceCheckURL = System.getProperty(PROPERTY_QUERY_URL);

      if (forceCheckURL != null) {
        branch.log(CHECK_INFO, "Explicit version check URL: " + forceCheckURL);
        queryURL = forceCheckURL;
      }

      // Get our unique user id (based on absolute timestamp).
      //
      long currentTimeMillis = System.currentTimeMillis();
      String firstLaunch = prefs.get(FIRST_LAUNCH, null);
      if (firstLaunch == null) {
        firstLaunch = Long.toHexString(currentTimeMillis);
        prefs.put(FIRST_LAUNCH, firstLaunch);
        branch.log(CHECK_SPAM, "Setting first launch to " + firstLaunch);
      } else {
        branch.log(CHECK_SPAM, "First launch was " + firstLaunch);
      }

      // See if enough time has passed.
      //
      String lastPing = prefs.get(LAST_PING, "0");
      if (lastPing != null) {
        try {
          long lastPingTime = Long.parseLong(lastPing);
          if (currentTimeMillis < lastPingTime + minCheckMillis) {
            // it's not time yet
            branch.log(CHECK_INFO, "Last ping was " + new Date(lastPingTime)
                + ", min wait is " + minCheckMillis + "ms");
            return null;
          }
        } catch (NumberFormatException e) {
          branch.log(CHECK_WARN, "Error parsing last ping time", e);
        }
      }

      // See if it's time for our next ping yet.
      //
      String nextPing = prefs.get(NEXT_PING, "0");
      if (nextPing != null) {
        try {
          long nextPingTime = Long.parseLong(nextPing);
          if (currentTimeMillis < nextPingTime) {
            // it's not time yet
            branch.log(CHECK_INFO, "Next ping is not until "
                + new Date(nextPingTime));
            return null;
          }
        } catch (NumberFormatException e) {
          branch.log(CHECK_WARN, "Error parsing next ping time", e);
        }
      }

      // See if new version is available.
      //
      String url = queryURL + "?v=" + myVersion.toString() + "&id="
          + firstLaunch + "&r=" + About.getGwtGitRev();
      if (entryPoint != null) {
        url += "&e=" + entryPoint;
      }

      branch.log(CHECK_INFO, "Checking for new version at " + url);

      // Do the HTTP GET.
      //
      String fullUserAgent = makeUserAgent();
      byte[] response = doHttpGet(branch, fullUserAgent, url);

      if (response == null || response.length == 0) {
        // Problem. Quietly fail.
        //
        branch.log(CHECK_ERROR,
            "Failed to obtain current version info via HTTP");
        return null;
      }

      // Parse and process the response.
      // Bad responses will be silently ignored.
      //
      return parseResponse(branch, prefs, response);

    } catch (Throwable e) {
      // Always silently ignore any errors.
      //
      branch.log(CHECK_INFO, "Exception while processing version info", e);
    }
    return null;
  }

  private byte[] doHttpGet(TreeLogger branch, String userAgent, String url) {
    Throwable caught;
    InputStream is = null;
    try {
      URL urlToGet = new URL(url);
      URLConnection conn = urlToGet.openConnection();
      conn.setRequestProperty("User-Agent", userAgent);
      is = conn.getInputStream();
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte[] buffer = new byte[4096];
      int bytesRead;
      while ((bytesRead = is.read(buffer)) != -1) {
        baos.write(buffer, 0, bytesRead);
      }
      byte[] response = baos.toByteArray();
      return response;
    } catch (MalformedURLException e) {
      caught = e;
    } catch (IOException e) {
      caught = e;
    } finally {
      if (is != null) {
        try {
          is.close();
        } catch (IOException e) {
        }
      }
    }

    if (System.getProperty(PROPERTY_DEBUG_HTTP_GET) != null) {
      branch.log(CHECK_ERROR, "Exception in HTTP request", caught);
    }

    return null;
  }

  private void appendUserAgentProperty(StringBuffer sb, String propName) {
    String propValue = System.getProperty(propName);
    if (propValue != null) {
      if (sb.length() > 0) {
        sb.append("; ");
      }
      sb.append(propName);
      sb.append("=");
      sb.append(propValue);
    }
  }

  /**
   * Creates a user-agent string by combining standard Java properties.
   */
  private String makeUserAgent() {
    String ua = "GWT Freshness Checker";

    StringBuffer extra = new StringBuffer();
    appendUserAgentProperty(extra, "java.vendor");
    appendUserAgentProperty(extra, "java.version");
    appendUserAgentProperty(extra, "os.arch");
    appendUserAgentProperty(extra, "os.name");
    appendUserAgentProperty(extra, "os.version");

    if (extra.length() > 0) {
      ua += " (" + extra.toString() + ")";
    }

    return ua;
  }

  private UpdateResult parseResponse(TreeLogger branch, Preferences prefs,
      byte[] response) throws IOException, ParserConfigurationException,
      SAXException {

    branch.log(CHECK_SPAM, "Parsing response (length " + response.length + ")");

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    ByteArrayInputStream bais = new ByteArrayInputStream(response);

    // Parse the XML.
    //
    builder.setErrorHandler(new ErrorHandler() {

      @Override
      public void error(SAXParseException exception) throws SAXException {
        // fail quietly
      }

      @Override
      public void fatalError(SAXParseException exception) throws SAXException {
        // fail quietly
      }

      @Override
      public void warning(SAXParseException exception) throws SAXException {
        // fail quietly
      }
    });
    Document doc = builder.parse(bais);

    // The latest version number.
    //
    String versionString = getTextOfLastElementHavingTag(doc, "latest-version");
    if (versionString == null) {
      // Not valid; quietly fail.
      //
      branch.log(CHECK_ERROR, "Failed to find <latest-version>");
      return null;
    }
    GwtVersion currentReleasedVersion;
    try {
      currentReleasedVersion = new GwtVersion(versionString.trim());
    } catch (NumberFormatException e) {
      branch.log(CHECK_ERROR, "Bad version: " + versionString, e);
      return null;
    }

    // Ping delay for server-controlled throttling.
    //
    String pingDelaySecsStr = getTextOfLastElementHavingTag(doc,
        "min-wait-seconds");
    int pingDelaySecs = 0;
    if (pingDelaySecsStr == null) {
      // Not valid; quietly fail.
      //
      branch.log(CHECK_ERROR, "Missing <min-wait-seconds>");
      return null;
    }
    try {
      pingDelaySecs = Integer.parseInt(pingDelaySecsStr.trim());
    } catch (NumberFormatException e) {
      // Not a valid number; quietly fail.
      //
      branch.log(CHECK_ERROR, "Bad min-wait-seconds number: "
          + pingDelaySecsStr);
      return null;
    }

    String url = getTextOfLastElementHavingTag(doc, "notification-url");

    if (url == null) {
      // no URL, so write the HTML locally and provide a URL from that

      // Read the HTML.
      //
      String html = getTextOfLastElementHavingTag(doc, "notification");

      if (html == null) {
        // Not valid; quietly fail.
        //
        branch.log(CHECK_ERROR, "Missing <notification>");
        return null;
      }
      PrintWriter writer = null;
      try {
        String tempDir = System.getProperty("java.io.tmpdir");
        File updateHtml = new File(tempDir, "gwt-update-"
            + currentReleasedVersion + ".html");
        writer = new PrintWriter(new FileOutputStream(updateHtml));
        writer.print(html);
        url = "file://" + updateHtml.getAbsolutePath();
      } finally {
        if (writer != null) {
          writer.close();
        }
      }
    }

    // Okay -- this is a valid response.
    //
    return processResponse(branch, prefs, currentReleasedVersion,
        pingDelaySecs, url);
  }

  private UpdateResult processResponse(TreeLogger branch, Preferences prefs,
      final GwtVersion serverVersion, int pingDelaySecs, final String notifyUrl) {

    // Record a ping; don't ping again until the delay is up.
    //
    long currentTimeMillis = System.currentTimeMillis();
    long nextPingTime = currentTimeMillis + pingDelaySecs * 1000;
    prefs.put(NEXT_PING, String.valueOf(nextPingTime));
    prefs.put(LAST_PING, String.valueOf(currentTimeMillis));

    branch.log(CHECK_INFO, "Ping delay is " + pingDelaySecs + "; next ping at "
        + new Date(nextPingTime));

    if (myVersion.isNoNagVersion()) {
      // If the version number indicates no nagging about updates, exit here
      // once we have recorded the next ping time. No-nag versions (ie,
      // trunk builds) should also not update the highest version that has been
      // run.
      return null;
    }

    // Update the highest version of GWT that has been run if we are later.
    GwtVersion highestRunVersion = new GwtVersion(prefs.get(
        HIGHEST_RUN_VERSION, null));
    if (myVersion.compareTo(highestRunVersion) > 0) {
      highestRunVersion = myVersion;
      prefs.put(HIGHEST_RUN_VERSION, highestRunVersion.toString());
    }

    // Are we up to date already?
    //
    if (highestRunVersion.compareTo(serverVersion) >= 0) {
      // Yes, we are.
      //
      branch.log(CHECK_INFO, "Server version (" + serverVersion
          + ") is not newer than " + highestRunVersion);
      return null;
    }

    // Commence nagging.
    //
    URL url = null;
    try {
      url = new URL(notifyUrl);
    } catch (MalformedURLException e) {
      logger.log(CHECK_ERROR, "Malformed notify URL: " + notifyUrl, e);
    }
    final URL finalUrl = url;
    return new UpdateResult() {
      @Override
      public GwtVersion getNewVersion() {
        return serverVersion;
      }

      @Override
      public URL getURL() {
        return finalUrl;
      }
    };
  }
}
