/*
 * Copyright 2011 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.
 */

/**
 * @fileoverview The implementation of the "Dev Mode On" and "Compile"
 * bookmarklets.
 *
 * The "Dev Mode On" bookmarklet displays a dialog at the top of the page
 * allowing the user to choose a GWT app to recompile. This dialog
 * contains a "Compile" bookmarklet for each available module.
 *
 * The "Compile" bookmarklet tells the code server to recompile a GWT app,
 * and if successful, reloads the current page with Super Dev Mode enabled.
 *
 * The bookmarklets themselves are just bootstrap scripts that set some
 * parameters on window and include this script. That way, users don't have
 * to delete and replace their bookmarklets when we change this code.
 */
(function() {
  var $doc = document;

  // Set up globals needed for JSONP calls. (These persist between bookmarklet
  // calls, in case the user clicks the bookmarklet more than once.)
  var globals = window.__gwt_bookmarklet_globals;
  if (typeof globals == 'undefined') {
    globals = {
      callback_counter: 0,
      callbacks: {},
      dismissModuleDialog: function() {}
    };
    window.__gwt_bookmarklet_globals = globals;
  }

  /**
   * Deletes and returns the parameters passed in by the "Dev Mode On" or
   * "Compile" bookmarklet. We expect the bookmarklet to pass the following
   * parameters:
   * <ul>
   *   <li>server_url The top-level URL of the code server, including the
   *       trailing slash.
   *   <li>module_name (optional) The name of the module to compile. (Skips
   *   the module dialog if the module is available.)
   * </ul>
   * @return {Object} The parameters, or null if not found.
   */
  function getBookmarkletParams() {
    var params = window.__gwt_bookmarklet_params;
    if (!params) {
      return null;
    }
    try {
      delete window.__gwt_bookmarklet_params;
    } catch (e) {
      // Delete window.x throws and exception in IE8.
      window['__gwt_bookmarklet_params'] = null;
    }
    return params;
  }

  /**
   * Creates an element and populates it with text.
   * Ensures that a text is black, regardless of style sheet.
   * @param tagName {string}
   * @param fontSize {string}
   * @param text {string}
   */
  function makeTextElt(tagName, fontSize, text) {
    var elt = $doc.createElement(tagName);
    elt.style.color = 'black';
    elt.style.background = 'white';
    elt.style.fontSize = fontSize;
    elt.appendChild($doc.createTextNode(text));
    return elt;
  }

  function makeOverlay() {
    var overlay = $doc.createElement('div');
    overlay.style.zIndex = 1000000;
    overlay.style.position = 'absolute';
    overlay.style.top = 0;
    overlay.style.left = 0;
    overlay.style.bottom = 0;
    overlay.style.right = 0;
    overlay.style.background = 'black'; // darken background
    overlay.style.opacity = '0.5';
    return overlay;
  }

  function makeDialog() {
    var dialog = $doc.createElement('div');
    dialog.style.zIndex = 1000001;
    dialog.style.position = 'fixed';
    dialog.style.top = '20pt';
    dialog.style.left = '20pt';
    dialog.style.right = '20pt';
    dialog.style.color = 'black';
    dialog.style.background = 'white';
    dialog.style.border = '4px solid #ccc';
    dialog.style.padding = '1em';
    dialog.style.borderRadius = '5px';
    dialog.style.wordWrap = 'break-word';
    return dialog;
  }

  function makeBookmarklet(name, javascript) {
    var result = makeTextElt('a', '12pt', name);
    result.style.fontFamily = 'sans';
    result.style.textDecoration = 'none';
    result.style.background = '#ddd';
    result.style.border = '2px outset #ddd';
    result.style.padding = '3pt';
    result.setAttribute('href', 'javascript:' + encodeURIComponent(javascript));
    result.title = 'Tip: drag this button to the bookmark bar';
    return result;
  }

  function makeCompileBookmarklet(codeserver_url, module_name) {
    var bookmarklets_js = codeserver_url + 'dev_mode_on.js';
    var javascript = '{ window.__gwt_bookmarklet_params = {'
        + 'server_url:\'' + codeserver_url + '\','
        + 'module_name:\'' + module_name + '\'};'
        + ' var s = document.createElement(\'script\');'
        + ' s.src = \'' + bookmarklets_js + '\';'
        + ' void(document.getElementsByTagName(\'head\')[0].appendChild(s));}';
    return makeBookmarklet('Compile', javascript);
  }

  /**
   * Determines whether we can recompile a module and see the results. If not,
   * explains why not.
   * @param module_name {string}
   * @return {string} The error message, or null if there is no error and
   *     a recompile will succeed.
   */
  function getCannotCompileError(module_name) {
    if (!isModuleOnCodeServer(module_name)) {
      return 'The code server isn\'t configured to compile this module.';
    }

    var modules_on_page = window.__gwt_activeModules;
    if (!modules_on_page || !(module_name in modules_on_page)) {
      return 'The current page doesn\'t have this module.';
    }

    var mod = modules_on_page[module_name];

    var dev_mode_key = '__gwtDevModeHook:' + module_name;
    var dev_mode_on = mod['superdevmode'] ||
        window.sessionStorage[dev_mode_key];

    if (!dev_mode_on && !mod.canRedirect) {
      return 'This module doesn\'t have Super Dev Mode enabled.';
    }

    // looks okay
    return null;
  }

  /**
   * Determines if the code server is configured to run the given module.
   * @param module_name {string}
   * @return {boolean} true if the code server supports the given module.
   */
  function isModuleOnCodeServer(module_name) {
    var modules_on_codeserver = window.__gwt_codeserver_config.moduleNames;
    // Support browsers without indexOf() (e.g. IE8).
    for (var i = 0; i < modules_on_codeserver.length; i++) {
      if (modules_on_codeserver[i] == module_name) {
        return true;
      }
    }
    return false;
  }

  /**
   * Displays the "Choose module to compile" dialog.
   * @param codeserver_url {string} The URL of the code server that will
   *    compile the chosen module.
   */
  function showModuleDialog(codeserver_url) {

    function makeHeader() {
      return makeTextElt('div', '20pt', 'Choose a module to recompile:');
    }

    function makeModuleRows(mod) {
      var module_name = mod.moduleName;
      var error = getCannotCompileError(module_name);
      var moduleColor = error ? 'grey' : 'black';

      var row = $doc.createElement('tr');

      // Bullet and module name
      var cell = $doc.createElement('td');
      var text = makeTextElt('span', '14pt', "\u2022 " + module_name + ": ");
      text.style.color = moduleColor;
      cell.appendChild(text);

      // Status (usually clickable)
      var status = makeTextElt('span', '14pt', mod.superdevmode ? "on" : "off");
      status.style.color = moduleColor;
      if (!error || status.superdevmode) {
        status.style.cursor = "pointer";
        status.onclick = function() {
          if (mod.superdevmode) {
            reloadWithoutDevMode(module_name);
          } else {
            reloadInDevMode(module_name, codeserver_url);
          }
          return false;
        };
        status.title = "Click to turn " +
            (mod.superdevmode ? "off." : "on without recompiling.") +
            " (Reloads the page.)";
      }
      cell.appendChild(status);

      row.appendChild(cell);

      if (!error) {
        // Compile button
        var button = makeCompileBookmarklet(codeserver_url, module_name);
        button.className = 'module_' + module_name;
        cell = $doc.createElement('td');
        cell.style.paddingLeft = '1em';
        cell.appendChild(button);
        row.appendChild(cell);
      }

      var rows = [row];
      if (error) {
        // Error message
        cell = makeTextElt('td', '10pt', error);
        cell.style.color = 'gray';

        row = $doc.createElement('tr');
        row.appendChild(cell);
        rows.push(row);
      }

      return rows;
    }

    function makeCodeServerLink() {
      var div = $doc.createElement('div');
      div.style.float = "right";

      var hostPort = codeserver_url.replace(/^http:\/\//, '').replace(/\/$/, '');
      var link = makeTextElt('a', '10pt', hostPort);
      link.style.textDecoration = "none";
      link.setAttribute('href', codeserver_url);
      link.setAttribute('target', '_blank');
      link.title = "The address of the server this bookmarklet uses to compile.";
      div.appendChild(link);
      return div;
    }

    function makeFooter() {
      var warnings = window.__gwt_codeserver_config.warnings;
      var div = $doc.createElement("div");
      if (warnings.length > 0) {
        div.style.marginTop = "10px";
      }
      div.appendChild(makeCodeServerLink());
      for (var i = 0; i < warnings.length; i++) {
        var warning = makeTextElt('div', '10pt', warnings[i]);
        div.appendChild(warning);
      }
      return div;
    }

    var active_modules = window.__gwt_activeModules;

    var moduleTable = $doc.createElement('table');
    moduleTable.style.marginTop = "10px";
    for (var module_name in active_modules) {
      var rows = makeModuleRows(active_modules[module_name]);
      for (var i = 0; i < rows.length; i++) {
        moduleTable.appendChild(rows[i]);
      }
    }

    // Assemble the dialog.
    var dialog = makeDialog();
    if (moduleTable.hasChildNodes()) {
      dialog.appendChild(makeHeader());
      dialog.appendChild(moduleTable);
    } else {
      dialog.appendChild(makeTextElt('span', '16pt',
          'Can\'t find any GWT Modules on this page.'));
    }
    dialog.appendChild(makeFooter());

    // Grey out everything under the dialog.
    var overlay = makeOverlay();

    var body = $doc.getElementsByTagName('body')[0];
    body.appendChild(overlay);
    body.appendChild(dialog);

    globals.dismissModuleDialog = function() {
      body.removeChild(dialog);
      body.removeChild(overlay);
      globals.dismissModuleDialog = function() {}; // uninstall
    };

    // Clicking outside the module dialog dismisses it.
    overlay.onclick = function() {
      globals.dismissModuleDialog();
    };
  }

  /**
   * Displays the "Compiling..." dialog.
   * @param {string} text A line of text to display.
   * @return {Object} An object representing the dialog. It
   *     has two methods, updateProgress and showError.
   */
  function showCompilingDialog(text) {
    // Grey out everything under the dialog.
    var overlay = makeOverlay();
    var dialog = makeDialog();

    var message = makeTextElt('div', '16pt', text);
    dialog.appendChild(message);

    var body = $doc.getElementsByTagName('body')[0];
    body.appendChild(overlay);
    body.appendChild(dialog);

    var result = {};

    /**
     * Updates the progress while compiling.
     */
    result.updateProgress = function(json) {
      // Just append a dot for now.
      message.appendChild($doc.createTextNode(" ."));
    };

    /**
     * Updates the dialog with an error message.
     * @param {string} errorText The text to display in red.
     * @param {string} log_url A URL that the error message should link to.
     * @param {function()} onClickTryAgain A callback for the
     *     "Try Again" button.
     */
    result.showError = function(errorText, log_url, onClickTryAgain) {
      var error = makeTextElt('a', '16pt', errorText);
      error.setAttribute('href', log_url);
      error.setAttribute('target', 'gwt_dev_mode_log');
      error.style.color = 'red';
      error.style.textDecoration = 'underline';
      message.appendChild(error);

      var button = makeTextElt('button', '12pt', 'Try Again');
      button.onclick = function() {
        body.removeChild(dialog);
        body.removeChild(overlay);
        onClickTryAgain();
      };
      dialog.appendChild(button);
    };

    return result;
  }

  /**
   * Makes a JSONP call. Assumes that the callback parameter is named
   * "callback". Handles multiple callbacks in flight at once.
   * @param {string} url_prefix A URL prefix that ends with '?' or '&'.
   * @param {function(Object)} callback A function to call with the result
   * of the JSONP call.
   */
  function callJsonp(url_prefix, callback) {
    var callback_id = 'c' + globals.callback_counter++;
    globals.callbacks[callback_id] = function(json) {
      delete globals.callbacks[callback_id];
      callback(json);
    };

    var url = url_prefix + '_callback=__gwt_bookmarklet_globals.callbacks.' +
        callback_id;

    var script = $doc.createElement('script');
    script.src = url;
    $doc.getElementsByTagName('head')[0].appendChild(script);
  }

  /**
   * Gets the binding properties to use for this recompile. The properties
   * come from the GWT application on the current page, with a fallback
   * to a cached value in session storage. (The cached value will normally
   * be used if the current page is already using dev mode.)
   * @param {string} module_name Identifies the GWT app we are recompiling.
   * @param {function} get_prop_map Returns the app's binding properties.
   * @return {string} Zero or more encoded url parameters; the string is
   * either empty or ends with '&'.
   */
  function getBindingParameters(module_name, get_prop_map) {
    var session_key = '__gwtDevModeSession:' + module_name;

    var prop_map = get_prop_map();
    var props = [];
    for (var key in prop_map) {
      props.push(encodePair(key, prop_map[key]));
    }

    if (!props.length) {
      // There is only one permutation, maybe because we're in dev mode already.
      // Use the cached value if present.
      var cached = window.sessionStorage[session_key];
      return cached || '';
    }

    var encoded = props.join('&') + '&';
    // Cache it for the next recompile.
    window.sessionStorage[session_key] = encoded;
    return encoded;
  }

  function encodePair(key, value) {
    return encodeURIComponent(key) + '=' + encodeURIComponent(value);
  }

  /**
   * Tells the GWT application to replace itself with a different version that
   * the code server is serving, then reloads the page. (This only works if
   * the GWT application was compiled with the new dev mode hook turned on in
   * the GWT linker.)
   *
   * @param {string} module_name The module to replace (after rename).
   * @param {string} codeserver_url The code server to use
   *     (with trailing slash).
   */
  function reloadInDevMode(module_name, codeserver_url) {
    var key = '__gwtDevModeHook:' + module_name;
    sessionStorage[key] = codeserver_url + module_name + '/' +
        module_name + '.nocache.js';
    window.location.reload();
  }

  /**
   * Turns dev mode off for the given module, then reloads the page.
   * @param {string} module_name
   */
  function reloadWithoutDevMode(module_name) {
    var key = '__gwtDevModeHook:' + module_name;
    sessionStorage.removeItem(key);
    window.location.reload();
  }

  /**
   * Displays the "compiling" dialog and starts the recompile.
   * @param {string} module_name The module to replace (after rename).
   * @param {string} codeserver_url The code server to use.
   * @param {function} get_prop_map Returns the app's binding properties.
   */
  function compile(module_name, codeserver_url, get_prop_map) {
    var dialog = showCompilingDialog('Compiling ' + module_name + '...');

    var compiling = false;
    var lastPollStart;

    function onPollFinished(event) {
        if (compiling && event.status == "compiling") {
            dialog.updateProgress(event);
            // Date.now() fails in IE8
            var waitTime = 1000 - (new Date().getTime() - lastPollStart);
            if (waitTime > 0) {
                setTimeout(poll, waitTime);
            } else {
                poll();
            }
        }
        // otherwise it's idle or an unknown event type, so stop
    }

    function poll() {
      if (compiling) {
          // Date.now() fails in IE8
          lastPollStart = new Date().getTime();
          callJsonp(codeserver_url + 'progress?', onPollFinished);
      }
    }

    function onClickTryAgain() {
      // Just start over from the beginning.
      compile(module_name, codeserver_url, get_prop_map);
    }

    function onCompileFinished(json) {
      globals.compiling = false;
      compiling = false;
      if (json.status != 'ok') {
        var log_url = codeserver_url + 'log/' + module_name;
        dialog.showError(json.status, log_url, onClickTryAgain);
        return;
      }
      reloadInDevMode(module_name, codeserver_url);
    }

    var url_prefix = codeserver_url + 'recompile/' + module_name + '?' +
    getBindingParameters(module_name, get_prop_map);
    globals.compiling = true;
    compiling = true;
    setTimeout(poll, 1000);
    callJsonp(url_prefix, onCompileFinished);
  }

  /**
   * Determines whether we should run the "Dev Mode On" or "Compile"
   * bookmarklet.
   * @param params {map} Parameters passed in by the bookmarklet.
   */
  function runBookmarklet(params) {
    if (!!globals.compiling) {
      // A module is already being compiled.
      // We ignore the bookmarklet: the page will reload once the compilation
      // ends.
      return;
    }
    if (!params || !params.server_url) {
      window.alert('Need to reinstall the bookmarklets.');
      return;
    }

    var module_name = params.module_name;

    var error = null;
    if (module_name) {
      error = getCannotCompileError(module_name);
    }

    if (module_name && !error) {
      // The user clicked a "Compile" bookmarklet and we believe it will
      // succeed.

      // Use the binding properties provided in params if available.
      // (This happens if we're being called from a stub rather than a bookmarklet.)
      var getPropMap = params.getPropMap;
      if (!getPropMap) {
        // Probably a regular compile, so check in the page.
        var active_modules = window.__gwt_activeModules;
        getPropMap = active_modules[module_name].bindings;
      }
      compile(module_name, params.server_url, getPropMap);
    } else {
      // The user clicked the "Dev Mode On" bookmarklet or something is wrong.
      showModuleDialog(params.server_url);
    }
  }

  // remove previous module dialog, if present
  if (globals.dismissModuleDialog) {
    globals.dismissModuleDialog();
  }

  runBookmarklet(getBookmarkletParams());
})();
