// Copyright (c) 2014, 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.

part of dart2js.js_emitter;

class MainCallStubGenerator {
  final Compiler compiler;
  final JavaScriptBackend backend;
  final CodeEmitterTask emitterTask;

  MainCallStubGenerator(this.compiler, this.backend, this.emitterTask);

  BackendHelpers get helpers => backend.helpers;

  /// Returns the code equivalent to:
  ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
  jsAst.Expression _buildIsolateSetupClosure(Element appMain,
                                             Element isolateMain) {
    jsAst.Expression mainAccess =
        emitterTask.isolateStaticClosureAccess(appMain);
    // Since we pass the closurized version of the main method to
    // the isolate method, we must make sure that it exists.
    return js('function(a){ #(#, a); }',
        [emitterTask.staticFunctionAccess(isolateMain), mainAccess]);
  }

  jsAst.Statement generateInvokeMain() {
    Element main = compiler.mainFunction;
    jsAst.Expression mainCallClosure = null;
    if (compiler.hasIsolateSupport) {
      Element isolateMain =
        helpers.isolateHelperLibrary.find(BackendHelpers.START_ROOT_ISOLATE);
      mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
    } else if (compiler.options.hasIncrementalSupport) {
      mainCallClosure = js(
          'function() { return #(); }',
          emitterTask.staticFunctionAccess(main));
    } else {
      mainCallClosure = emitterTask.staticFunctionAccess(main);
    }

    jsAst.Expression currentScriptAccess =
        emitterTask.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);

    // This code finds the currently executing script by listening to the
    // onload event of all script tags and getting the first script which
    // finishes. Since onload is called immediately after execution this should
    // not substantially change execution order.
    return js.statement('''
      (function (callback) {
        if (typeof document === "undefined") {
          callback(null);
          return;
        }
        // When running as a content-script of a chrome-extension the
        // 'currentScript' is `null` (but not undefined).
        if (typeof document.currentScript != 'undefined') {
          callback(document.currentScript);
          return;
        }

        var scripts = document.scripts;
        function onLoad(event) {
          for (var i = 0; i < scripts.length; ++i) {
            scripts[i].removeEventListener("load", onLoad, false);
          }
          callback(event.target);
        }
        for (var i = 0; i < scripts.length; ++i) {
          scripts[i].addEventListener("load", onLoad, false);
        }
      })(function(currentScript) {
        #currentScript = currentScript;

        if (typeof dartMainRunner === "function") {
          dartMainRunner(#mainCallClosure, []);
        } else {
          #mainCallClosure([]);
        }
      })''',
      {'currentScript': currentScriptAccess,
       'mainCallClosure': mainCallClosure});
  }
}
