// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview Deferred resource loader for OOBE/Login screens.
 */

cr.define('cr.ui.login.ResourceLoader', function() {
  'use strict';

  // Deferred assets.
  var ASSETS = {};

  /**
   * Register assets for deferred loading.  When the bundle is loaded
   * assets will be added to the current page's DOM: <link> and <script>
   * tags pointing to the CSS and JavaScript will be added to the
   * <head>, and HTML will be appended to a specified element.
   *
   * @param {Object} desc Descriptor for the asset bundle
   * @param {string} desc.id Unique identifier for the asset bundle.
   * @param {Array=} desc.js URLs containing JavaScript sources.
   * @param {Array=} desc.css URLs containing CSS rules.
   * @param {Array<Object>=} desc.html Descriptors for HTML fragments,
   * each of which has a 'url' property and a 'targetID' property that
   * specifies the node under which the HTML should be appended.
   *
   * Example:
   *   ResourceLoader.registerAssets({
   *     id: 'bundle123',
   *     js: ['//foo.com/src.js', '//bar.com/lib.js'],
   *     css: ['//foo.com/style.css'],
   *     html: [{ url: '//foo.com/tmpls.html' targetID: 'tmpls'}]
   *   });
   *
   * Note: to avoid cross-site requests, all HTML assets must be served
   * from the same host as the rendered page.  For example, if the
   * rendered page is served as chrome://oobe, then all the HTML assets
   * must be served as chrome://oobe/path/to/something.html.
   */
  function registerAssets(desc) {
    var html = desc.html || [];
    var css = desc.css || [];
    var js = desc.js || [];
    ASSETS[desc.id] = {
      html: html, css: css, js: js,
      loaded: false,
      count: html.length + css.length + js.length
    };
  }

  /**
   * Determines whether an asset bundle is defined for a specified id.
   * @param {string} id The possible identifier.
   */
  function hasDeferredAssets(id) {
    return id in ASSETS;
  }

  /**
   * Determines whether an asset bundle has already been loaded.
   * @param {string} id The identifier of the asset bundle.
   */
  function alreadyLoadedAssets(id) {
    return hasDeferredAssets(id) && ASSETS[id].loaded;
  }

  /**
   * Load a stylesheet into the current document.
   * @param {string} id Identifier of the stylesheet's asset bundle.
   * @param {string} url The URL resolving to a stylesheet.
   */
  function loadCSS(id, url) {
    var link = document.createElement('link');
    link.setAttribute('rel', 'stylesheet');
    link.setAttribute('href', url);
    link.onload = resourceLoaded.bind(null, id);
    document.head.appendChild(link);
  }

  /**
   * Load a script into the current document.
   * @param {string} id Identifier of the script's asset bundle.
   * @param {string} url The URL resolving to a script.
   */
  function loadJS(id, url) {
    var script = document.createElement('script');
    script.src = url;
    script.onload = resourceLoaded.bind(null, id);
    document.head.appendChild(script);
  }

  /**
   * Move DOM nodes from one parent element to another.
   * @param {HTMLElement} from Element whose children should be moved.
   * @param {HTMLElement} to Element to which nodes should be appended.
   */
  function moveNodes(from, to) {
    Array.prototype.forEach.call(from.children, function(child) {
      to.appendChild(document.importNode(child, true));
    });
  }

  /**
   * Tests whether an XMLHttpRequest has successfully finished loading.
   * @param {string} url The requested URL.
   * @param {XMLHttpRequest} xhr The XHR object.
   */
  function isSuccessful(url, xhr) {
    var fileURL = /^file:\/\//;
    return xhr.readyState == 4 &&
        (xhr.status == 200 || fileURL.test(url) && xhr.status == 0);
  }

  /*
   * Load a chunk of HTML into the current document.
   * @param {string} id Identifier of the page's asset bundle.
   * @param {Object} html Descriptor of the HTML to fetch.
   * @param {string} html.url The URL resolving to some HTML.
   * @param {string} html.targetID The element ID to which the retrieved
   * HTML nodes should be appended.
   */
  function loadHTML(id, html) {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', html.url);
    xhr.onreadystatechange = function() {
      if (isSuccessful(html.url, xhr)) {
        moveNodes(this.responseXML.body, $(html.targetID));
        resourceLoaded(id);
      }
    };
    xhr.responseType = 'document';
    xhr.send();
  }

  /**
   * Record that a resource has been loaded for an asset bundle.  When
   * all the resources have been loaded the callback that was specified
   * in the loadAssets call is invoked.
   * @param {string} id Identifier of the asset bundle.
   */
  function resourceLoaded(id) {
    var assets = ASSETS[id];
    assets.count--;
    if (assets.count == 0)
      finishedLoading(id);
  }

  /**
   * Finishes loading an asset bundle.
   * @param {string} id Identifier of the asset bundle.
   */
  function finishedLoading(id) {
    var assets = ASSETS[id];
    console.log('Finished loading asset bundle', id);
    assets.loaded = true;
    window.setTimeout(function() {
      assets.callback();
      chrome.send('screenAssetsLoaded', [id]);
    }, 0);
  }

  /**
   * Load an asset bundle, invoking the callback when finished.
   * @param {string} id Identifier for the asset bundle to load.
   * @param {function()=} callback Function to invoke when done loading.
   */
  function loadAssets(id, callback) {
    var assets = ASSETS[id];
    assets.callback = callback || function() {};
    console.log('Loading asset bundle', id);
    if (alreadyLoadedAssets(id))
      console.warn('asset bundle', id, 'already loaded!');
    if (assets.count == 0) {
      finishedLoading(id);
    } else {
      assets.css.forEach(loadCSS.bind(null, id));
      assets.js.forEach(loadJS.bind(null, id));
      assets.html.forEach(loadHTML.bind(null, id));
    }
  }

  return {
    alreadyLoadedAssets: alreadyLoadedAssets,
    hasDeferredAssets: hasDeferredAssets,
    loadAssets: loadAssets,
    registerAssets: registerAssets
  };
});
