// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This script dynamically prepares a set of files to run polymer.dart. It uses
// the html_import polyfill to search for all imported files, then
// it inlines all <polymer-element> definitions on the top-level page (needed by
// registerPolymerElement), and it removes script tags that appear inside
// those tags. It finally rewrites the main entrypoint to call an initialization
// function on each of the declared <polymer-elements>.
//
// This script is needed only when running polymer.dart in Dartium. It should be
// removed by the polymer deployment commands.

// As an example, given an input of this form:
//   <polymer-element name="c1">
//      <template></template>
//      <script type="application/dart" src="url0.dart"></script>
//   </polymer-element>
//   <element name="c2">
//      <template></template>
//      <script type="application/dart">main() => { print('body2'); }</script>
//   </element>
//   <c1></c1>
//   <c2></c2>
//   <script type="application/dart" src="url2.dart"></script>
//   <script src="packages/polymer/boot.js"></script>
//
// This script will simplifies the page as follows:
//   <polymer-element name="c1">
//      <template></template>
//   </polymer-element>
//   <polymer-element name="c2">
//      <template></template>
//   </polymer-element>
//   <c1></c1>
//   <c2></c2>
//   <script type="application/dart">
//     import 'url0.dart' as i0;
//     import "data:application/dart;base64,CiAgICBtYWluKCkgewogICAgICBwcmludCgnYm9keTInKTsKICAgIH0KICAgIA==" as i1;
//     import 'url2.dart' as i2;
//     ...
//     main() {
//       // code that checks which libraries have a 'main' and invokes them.
//       // practically equivalent to: i0._init(); i1._init(); i2.main();
//     }
//   </script>


(function() {
  // Only run in Dartium.
  if (!navigator.webkitStartDart) {
    // TODO(sigmund): rephrase when we split build.dart in two: analysis vs
    // deploy pieces.
    console.warn('boot.js only works in Dartium. Run the build.dart' +
      ' tool to compile a depolyable JavaScript version')
    return;
  }
  document.write(
    '<script src="packages/html_import/html_import.min.js"></script>');

  // Extract a Dart import URL from a script tag, which is the 'src' attribute
  // of the script tag, or a data-url with the script contents for inlined code.
  function getScriptUrl(script) {
    var url = script.src;
    if (url) {
      // Normalize package: urls
      var index = url.indexOf('packages/');
      if (index == 0 || (index > 0 && url[index - 1] == '/')) {
        url = "package:" + url.slice(index + 9);
      }
      return url;
    } else {
      // TODO(sigmund): investigate how to eliminate the warning in Dartium
      // (changing to text/javascript hides the warning, but seems wrong).
      return "data:application/dart;base64," + window.btoa(script.textContent);
    }
  }

  // Moves <polymer-elements> from imported documents into the top-level page.
  function inlinePolymerElements(content, ref, seen) {
    if (!seen) seen = {};
    var links = content.querySelectorAll('link[rel="import"]');
    for (var i = 0; i < links.length; i++) {
      var link = links[i].import;
      if (seen[link.href]) continue;
      seen[link.href] = link;
      inlinePolymerElements(link.content, ref, seen);
    }

    if (content != document) { // no need to do anything for the top-level page
      var elements = content.querySelectorAll('polymer-element');
      for (var i = 0; i < elements.length; i++)  {
        document.body.insertBefore(elements[i], ref);
      }
    }
  }

  // Creates a Dart program that imports [urls] and passes them to initPolymer
  // (which in turn will invoke their main function, their methods marked with
  // @initMethod, and register any custom tag labeled with @CustomTag).
  function createMain(urls, mainUrl) {
    var imports = Array(urls.length + 1);
    for (var i = 0; i < urls.length; ++i) {
      imports[i] = 'import "' + urls[i] + '" as i' + i + ';';
    }
    imports[urls.length] = 'import "package:polymer/polymer.dart" as polymer;';
    var arg = urls.length == 0 ? '[]' :
        ('[\n      "' + urls.join('",\n      "') + '"\n     ]');
    return (imports.join('\n') +
        '\n\nmain() {\n' +
        '  polymer.initPolymer(' + arg + ');\n' +
        '}\n');
  }

  // Finds all top-level <script> tags, and <script> tags in custom elements
  // and merges them into a single entrypoint.
  function mergeScripts() {
    var scripts = document.getElementsByTagName("script");
    var length = scripts.length;

    var urls = [];
    var toRemove = [];

    // Collect the information we need to replace the script tags
    for (var i = 0; i < length; ++i) {
      var script = scripts[i];
      if (script.type == "application/dart") {
        urls.push(getScriptUrl(script));
        toRemove.push(script);
      }
    }

    toRemove.forEach(function (s) { s.parentNode.removeChild(s); });

    // Append a new script tag that initializes everything.
    var newScript = document.createElement('script');
    newScript.type = "application/dart";
    newScript.textContent = createMain(urls);
    document.body.appendChild(newScript);
  }

  var alreadyRan = false;
  window.addEventListener('HTMLImportsLoaded', function (e) {
    if (alreadyRan) {
      console.warn('HTMLImportsLoaded fired again.');
      return;
    }
    alreadyRan = true;
    var ref = document.body.children[0];
    inlinePolymerElements(document, ref);
    mergeScripts();
    if (!navigator.webkitStartDart()) {
      document.body.innerHTML = 'This build has expired. Please download a ' +
          'new Dartium at http://www.dartlang.org/dartium/index.html';
    }
  });
})();
