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

// Export into our name space
// We do not consider any of these classes a public API and they will be changed as needed.
$namespace.lib = $namespace.lib || {};

StringHelper = {};

StringHelper.endsWith = function(str, suffix) {
  return str.indexOf(suffix, str.length - suffix.length) !== -1;
};

StringHelper.removeQueryString = function(str) {
  return str.split("#")[0].split("?")[0];
};

$namespace.lib.StringHelper = StringHelper;

/**
 * A PropertySource computes the binding properties to use for calling the GWT compiler.
 *
 * @constructor
 * @param {string} moduleName - the name of the gwt module
 * @param {Function} propertyProvidersHolder - a function returning property providers and
 *                       their values when invoked.
 * @param {MetaTagParser} metaTagParser - an instance of {@link MetaTagParser}
 */
function PropertySource(moduleName, propertyProvidersHolder, metaTagParser) {
  this.__moduleName = moduleName;
  this.__metaTagParser = metaTagParser;
  var props = this.__getProvidersAndValues(propertyProvidersHolder);
  this.__propertyProviders = props.providers;
  this.__propertyValues = props.values;
}

/**
 * Setup the environment that property providers need to run and initialize property providers
 * with that environment.
 *
 * @returns an object containing property providers and possible values.
 */
PropertySource.prototype.__getProvidersAndValues = function(propertyProvidersHolder) {
  // Setup scope for property providers
  var that = this;

  //Used by LocalePropertyGenerator
  var __gwt_getMetaProperty = function(name) {
    return that.__metaTagParser.get()[name];
  };

  // Used by LocalePropertyGenerator
  var __gwt_isKnownPropertyValue = function(propName, propValue) {
    return propValue in that.__propertyValues[propName];
  };

  // This function is defined in recompile_template.js and parameters being passed here need to be
  // kept in sync.
  return propertyProvidersHolder(__gwt_getMetaProperty, __gwt_isKnownPropertyValue);
};

/**
 * Compute the binding property value for a given property name.
 *
 * @param {string} propName - the binding property name
 * @returns {string} the computed value of the binding property
 */
PropertySource.prototype.__computePropValue = function(propName) {
  var val = this.__propertyProviders[propName]();
  // sanity check
  var allowedValuesMap = this.__propertyValues[propName];
  if (val in allowedValuesMap) {
    return val;
  } else {
    // TODO(dankurka): trigger this error in the ui
    // IE8 only has console defined if its dev tools have been opened before
    if ($wnd.console && $wnd.console.log) {
      $wnd.console.log("provider for " + propName
          + " returned unexpected value: '" + val + "'");
    }
    throw "can't compute binding property value for " + propName;
  }
};

/**
 * Compute all binding properties for a given module.
 * @returns {Object} a map of from binding properties to their current values
 */
PropertySource.prototype.computeBindingProperties = function() {
  var result = {};
  for (var key in this.__propertyValues) {
    if (this.__propertyValues.hasOwnProperty(key)) {
      result[key] = this.__computePropValue(key);
    }
  }
  return result;
};

$namespace.lib.PropertySource = PropertySource;

/**
 * Create a dialog.
 * @constructor
 */
function Dialog() {
  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';
  this.__dialog = dialog;

  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';
  this.__overlay = overlay;
}

/**
 * Create a DOM node with a given text.
 * @returns {external:Node} the node with the given text.
 */
Dialog.prototype.createTextElement = function(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;
};

/**
 * Add a node to the dialog.
 * @param {external:Node} node - the node to add to the dialog
 */
Dialog.prototype.add = function(node) {
  this.__dialog.appendChild(node);
};

/**
 * Remove all children from the dialog.
 */
Dialog.prototype.clear = function() {
  while (this.__dialog.firstChild) {
    this.__dialog.removeChild(this.__dialog.firstChild);
  }
};

/**
 * Show the dialog (add it to the body).
 */
Dialog.prototype.show = function() {
  $doc.body.appendChild(this.__overlay);
  $doc.body.appendChild(this.__dialog);
};

/**
 * Hide the dialog (remove it from the body).
 */
Dialog.prototype.hide = function() {
  $doc.body.removeChild(this.__overlay);
  $doc.body.removeChild(this.__dialog);
};

//Export Dialog to namespace
$namespace.lib.Dialog = Dialog;

/**
 * Construct a Recompiler object.
 * @constructor
 * @param {string} moduleName - the name of the gwt module
 * @param {Object} permutationProperties - A map of binding property names (string) to their values (string).
 * @returns
 */
function Recompiler(moduleName, permutationProperties) {
  if ($wnd.__gwt_sdm_globals) {
    this.__globals = $wnd.__gwt_sdm_globals;
  } else {
    this.__globals = {
      callbackCounter: new Date().getTime(), // avoid cache hits
      callbacks: {}
    };
    $wnd.__gwt_sdm_globals = this.__globals;
  }
  this.__moduleName = moduleName;
  this.__permutationProperties = permutationProperties;
  this.__compiling = false;
}

/**
 * Build the url that triggers a compile on the code server.
 * @returns {string} the url
 */
Recompiler.prototype.__buildCompileUrl = function() {
  var url = this.getCodeServerBaseUrl() + 'recompile/' + this.__moduleName + '?';
  var props = [];
  for (var key in this.__permutationProperties) {
    props.push($wnd.encodeURIComponent(key) + '=' +
        $wnd.encodeURIComponent(this.__permutationProperties[key]));
  }
  return url + props.join('&');
};

/**
 * Issue a compile request for the module of this Recompiler class.
 * @param {Function} finishCallback - the callback to invoke once compile finishes
 */
Recompiler.prototype.compile = function(finishCallback) {
  var that = this;
  this.__compiling = true;
  var compileUrl = this.__buildCompileUrl();
  this.__jsonp(compileUrl, function(data) {
    that.__compiling = false;
    finishCallback(data);
  });
};

/**
 * Issue a jsonp request.
 * @param {string} url - the url to use
 * @param {Function} callback - the callback to invoke
 */
Recompiler.prototype.__jsonp = function(url, callback) {
  var that = this;
  var callback_id = 'c' + this.__globals.callbackCounter++;
  this.__globals.callbacks[callback_id] = function(json) {
    delete that.__globals.callbacks[callback_id];
    callback(json);
  };

  var url = url + '&_callback=__gwt_sdm_globals.callbacks.' + callback_id;
  this.__injectScriptTag(url);
};

Recompiler.prototype.__injectScriptTag = function(url) {
  var script = $doc.createElement('script');
  script.src = url;
  var $head = $doc.head || $doc.getElementsByTagName('head')[0];
  $head.appendChild(script);
};

/**
 * Get protocol and host from a url.
 * @param {string} url
 */
Recompiler.prototype.__getBaseUrl = function(url) {
  var a = $doc.createElement('a');
  a.href = url;
  return a.protocol + '//' + a.host + '/';
};

/**
 * Get the base url of the code server.
 * @returns {string} the url of the code server
 */
Recompiler.prototype.getCodeServerBaseUrl = function() {
  var scriptTagsToSearch = $doc.getElementsByTagName('script');
  var expectedSuffix = '/recompile-requester/' + this.__moduleName;
  for (var i = 0; i < scriptTagsToSearch.length; i++) {
    var candidate = StringHelper.removeQueryString(scriptTagsToSearch[i].src);
    if (StringHelper.endsWith(candidate, expectedSuffix)) {
      return this.__getBaseUrl(candidate);
    }
  }
  throw "unable to find the script tag that includes /recompile-requester/" + moduleName ;
};

/**
 * Load the compiled application
 */
Recompiler.prototype.loadApp = function() {
  var url = this.getCodeServerBaseUrl() + this.__moduleName + '/' + this.__moduleName + '.nocache.js';
  var scriptTag = $doc.createElement('script');
  scriptTag.src = url;
  var $head = $doc.head || $doc.getElementsByTagName('head')[0];
  $head.insertBefore(scriptTag, $head.firstElementChild || $head.children[0]);
};

Recompiler.prototype.getLogUrl = function() {
  return this.getCodeServerBaseUrl() + 'log/' + this.__moduleName;
};

//Export Recompiler to namespace
$namespace.lib.Recompiler = Recompiler;

function MetaTagParser(moduleName) {
  this.__parsed = false;
  this.__metaProperties = null;
  this.__moduleName = moduleName;
}

MetaTagParser.prototype.__getMetaTags = function() {
  return $doc.getElementsByTagName('meta');
};

MetaTagParser.prototype.__parse = function() {
  var metaProps = {};
  var metas = this.__getMetaTags();

  for (var i = 0, n = metas.length; i < n; ++i) {
    var meta = metas[i];
    var name = meta.getAttribute('name');
    var content = meta.getAttribute('content');

    if (name) {
      name = name.replace(this.__moduleName + '::', '');
      if (name.indexOf('::') >= 0) {
        // It's for a different module
        continue;
      }
    }
    if (name == 'gwt:property' && content) {
      var value;
      var eq = content.indexOf('=');
      if (eq >= 0) {
        name = content.substring(0, eq);
        value = content.substring(eq+1);
      } else {
        name = content;
        value = '';
      }
      metaProps[name] = value;
    }
  }
  return metaProps;
};

MetaTagParser.prototype.get = function() {
  if (!this.__parsed) {
    this.__metaProperties = this.__parse();
    this.__parsed = true;
  }
  return this.__metaProperties;
};

//Export MetaTagParser to namespace
$namespace.lib.MetaTagParser = MetaTagParser;

/**
 * BaseUrlProvider provides the url to the original server that the app has been loaded from.
 * This is not the url of super dev mode.
 *
 * @constructor
 * @param {string} moduleName - the module for which we should determine the base url.
 */
function BaseUrlProvider(moduleName, metaTagParser) {
  this.__moduleName = moduleName;
  this.__metaTagParser = metaTagParser;
}

BaseUrlProvider.prototype.__getScriptTags = function() {
  return $doc.getElementsByTagName('script');
};

BaseUrlProvider.prototype.__stripHashQueryAndFileName = function(url) {
  // Truncate starting at the first '?' or '#', whichever comes first.
  var hashIndex = url.lastIndexOf('#');
  if (hashIndex == -1) {
    hashIndex = url.length;
  }

  var queryIndex = url.indexOf('?');
  if (queryIndex == -1) {
    queryIndex = url.length;
  }

  var slashIndex = url.lastIndexOf('/', Math.min(queryIndex, hashIndex));
  if (slashIndex < 0) {
    throw new 'Cannot find slash in: ' + url;
  }

  return url.substring(0, slashIndex + 1);
};

BaseUrlProvider.prototype.__maybeConvertToAbsoluteUrl = function(url) {
  // test for valid protocol starts
  if ((url.match(/^(?:(?:https)|(?:http)|(?:file)):\/\//))) {
    return url;
  }

  // Probably a relative URL; use magic to make the browser absolutify it.
  // I wish there were a better way to do this, but this seems the only
  // sure way!  (A side benefit is it preloads clear.cache.gif)
  // Note: this trick is harmless if the URL was really already absolute.
  var img = $doc.createElement("img");
  img.src = url + 'clear.cache.gif';
  return this.__stripHashQueryAndFileName(img.src);
};

BaseUrlProvider.prototype.getBaseUrl = function() {
  // This code follows the order in com/google/gwt/core/ext/linker/impl/computeScriptBase.js
  // Try to get the url from a meta property first
  var url = this.__getBaseUrlFromMetaTag();
  if (url) {
    return this.__maybeConvertToAbsoluteUrl(url);
  }

  // try the nocache next
  var expectedSuffix = this.__moduleName + '.nocache.js';
  var scriptTags = this.__getScriptTags();
  for (var i = 0; i < scriptTags.length; i++) {
    var candidate = StringHelper.removeQueryString(scriptTags[i].src);
    if (StringHelper.endsWith(candidate, expectedSuffix)) {
      var stripedUrl = this.__stripHashQueryAndFileName(candidate);
      return this.__maybeConvertToAbsoluteUrl(stripedUrl);
    }
  }

  //try the base tag
  var baseElements = this.__getBaseElements();
  if (baseElements.length > 0) {
    // It's always the last parsed base tag that will apply to this script.
    var baseElementUrl = baseElements[baseElements.length - 1].href;
    return this.__maybeConvertToAbsoluteUrl(baseElementUrl);
  }

  // Now we are getting desperate and as a last resort we try the current doc
  var fallbackUrl = this.__stripHashQueryAndFileName($doc.location.href);
  return this.__maybeConvertToAbsoluteUrl(fallbackUrl);
};

BaseUrlProvider.prototype.__getBaseElements = function() {
  return $doc.getElementsByTagName('base');
};

BaseUrlProvider.prototype.__getBaseUrlFromMetaTag = function() {
  return this.__metaTagParser.get()['baseUrl'];
};

//Export BaseUrlProvider to namespace
$namespace.lib.BaseUrlProvider = BaseUrlProvider;
