<!DOCTYPE html>
<!--
Copyright (c) 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.
-->

<link rel="import" href="/base/event.html">
<link rel="import" href="/base/event_target.html">
<link rel="import" href="/base/iteration_helpers.html">
<link rel="import" href="/base/unittest/test_suite.html">
<link rel="import" href="/base/xhr.html">

<script>
'use strict';

tr.exportTo('tr.b.unittest', function() {
  function HTMLImportsModuleLoader() {
  }
  HTMLImportsModuleLoader.prototype = {
    loadModule: function(testRelpath, moduleName) {
      return new Promise(function(resolve, reject) {
        var importEl = document.createElement('link');
        importEl.moduleName = moduleName;
        importEl.setAttribute('rel', 'import');
        importEl.setAttribute('href', testRelpath);

        importEl.addEventListener('load', function() {
          resolve({testRelpath: testRelpath,
                   moduleName: moduleName});
        });
        importEl.addEventListener('error', function(e) {
          reject('Error loading &#60;link rel="import" href="' +
                 testRelpath + '"');
        });

        tr.doc.head.appendChild(importEl);
      });
    },

    getCurrentlyExecutingModuleName: function() {
      if (!document.currentScript)
        throw new Error('Cannot call testSuite except during load.');
      var linkDoc = document.currentScript.ownerDocument;
      var url = linkDoc.URL;
      var name = this.guessModuleNameFromURL_(url);
      return name;
    },

    guessModuleNameFromURL_: function(url) {
      var m = /.+?:\/\/.+?(\/.+)/.exec(url);
      if (!m)
        throw new Error('Guessing module name failed');
      var path = m[1];
      if (path[0] != '/')
        throw new Error('malformed path');
      if (path.substring(path.length - 5) != '.html')
        throw new Error('Cannot define testSuites outside html imports');
      var parts = path.substring(1, path.length - 5).split('/');
      return parts.join('.');
    }
  };

  function D8ModuleLoader() {
    this.currentlyExecutingModuleInfo_ = undefined;
  }
  D8ModuleLoader.prototype = {
    loadModule: function(testRelpath, moduleName) {
      return Promise.resolve().then(function() {
        var moduleInfo = {
            testRelpath: testRelpath,
            moduleName: moduleName
        };
        if (this.currentlyExecutingModuleInfo_ !== undefined)
          throw new Error('WAT');
        this.currentlyExecutingModuleInfo_ = moduleInfo;

        try {
          loadHTML(testRelpath);
        } catch (e) {
          e.message = 'While loading ' + moduleName + ', ' + e.message;
          e.stack = 'While loading ' + moduleName + ', ' + e.stack;
          throw e;
        } finally {
          this.currentlyExecutingModuleInfo_ = undefined;
        }

        return moduleInfo;
      }.bind(this));
    },

    getCurrentlyExecutingModuleName: function() {
      if (this.currentlyExecutingModuleInfo_ === undefined)
        throw new Error('No currently loading module');
      return this.currentlyExecutingModuleInfo_.moduleName;
    }
  };


  function SuiteLoader(suiteRelpathsToLoad) {
    tr.b.EventTarget.call(this);

    this.currentModuleLoader_ = undefined;
    this.testSuites = [];

    if (tr.isHeadless) {
      if (!tr.isD8)
        throw new Error('No module loader exists fro this platform');
      this.currentModuleLoader_ = new D8ModuleLoader();
    } else {
      this.currentModuleLoader_ = new HTMLImportsModuleLoader();
    }

    this.allSuitesLoadedPromise = this.beginLoadingModules_(
        suiteRelpathsToLoad);
  }

  SuiteLoader.prototype = {
    __proto__: tr.b.EventTarget.prototype,

    beginLoadingModules_: function(testRelpaths) {
      // Hooks!
      this.bindGlobalHooks_();

      // Load the modules.
      var modulePromises = [];
      for (var i = 0; i < testRelpaths.length; i++) {
        var testRelpath = testRelpaths[i];
        var moduleName = testRelpath.split('/').slice(-1)[0];

        var p = this.currentModuleLoader_.loadModule(testRelpath, moduleName);
        modulePromises.push(p);
      }

      var allModulesLoadedPromise = new Promise(function(resolve, reject) {
        var remaining = modulePromises.length;
        var resolved = false;
        function oneMoreLoaded() {
          if (resolved)
            return;
          remaining--;
          if (remaining > 0)
            return;
          resolved = true;
          resolve();
        }

        function oneRejected(e) {
          if (resolved)
            return;
          resolved = true;
          reject(e);
        }

        modulePromises.forEach(function(modulePromise) {
          modulePromise.then(oneMoreLoaded, oneRejected);
        });
      });

      // Script errors errors abort load;
      var scriptErrorPromise = new Promise(function(xresolve, xreject) {
        this.scriptErrorPromiseResolver_ = {
          resolve: xresolve,
          reject: xreject
        };
      }.bind(this));
      var donePromise = Promise.race([
        allModulesLoadedPromise,
        scriptErrorPromise
      ]);

      // Cleanup.
      return donePromise.then(
        function() {
          this.scriptErrorPromiseResolver_ = undefined;
          this.unbindGlobalHooks_();
        }.bind(this),
        function(e) {
          this.scriptErrorPromiseResolver_ = undefined;
          this.unbindGlobalHooks_();
          throw e;
        }.bind(this));
    },

    bindGlobalHooks_: function() {
      if (global._currentSuiteLoader !== undefined)
        throw new Error('A suite loader exists already');
      global._currentSuiteLoader = this;

      this.oldGlobalOnError_ = global.onerror;
      global.onerror = function(errorMsg, url, lineNumber) {
        this.scriptErrorPromiseResolver_.reject(
            new Error(errorMsg + '\n' + url + ':' + lineNumber));
        if (this.oldGlobalOnError_)
          return this.oldGlobalOnError_(errorMsg, url, lineNumber);
        return false;
      }.bind(this);
    },

    unbindGlobalHooks_: function() {
      global._currentSuiteLoader = undefined;

      global.onerror = this.oldGlobalOnError_;
      this.oldGlobalOnError_ = undefined;
    },

    constructAndRegisterTestSuite: function(suiteConstructor) {
      var name = this.currentModuleLoader_.getCurrentlyExecutingModuleName();

      var testSuite = new tr.b.unittest.TestSuite(
        name, suiteConstructor);

      this.testSuites.push(testSuite);

      var e = new tr.b.Event('suite-loaded');
      e.testSuite = testSuite;
      this.dispatchEvent(e);
    },

    getAllTests: function() {
      var tests = [];
      this.testSuites.forEach(function(suite) {
        tests.push.apply(tests, suite.tests);
      });
      return tests;
    },

    findTestWithFullyQualifiedName: function(fullyQualifiedName) {
      for (var i = 0; i < this.testSuites.length; i++) {
        var suite = this.testSuites[i];
        for (var j = 0; j < suite.tests.length; j++) {
          var test = suite.tests[j];
          if (test.fullyQualifiedName == fullyQualifiedName)
            return test;
        }
      }
      throw new Error('Test ' + fullyQualifiedName +
                      'not found amongst ' + this.testSuites.length);
    }
  };

  return {
    SuiteLoader: SuiteLoader
  };
});
</script>
