// 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.

library dart2js.js_emitter.main_call_stub_generator;

import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;

import '../common_elements.dart';
import '../elements/entities.dart';
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
import '../js_backend/backend_usage.dart' show BackendUsage;

import 'code_emitter_task.dart' show Emitter;

class MainCallStubGenerator {
  final CommonElements _commonElements;
  final Emitter _emitter;
  final BackendUsage _backendUsage;

  MainCallStubGenerator(
      this._commonElements, this._emitter, this._backendUsage);

  /// Returns the code equivalent to:
  ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
  jsAst.Expression _buildIsolateSetupClosure(
      FunctionEntity appMain, FunctionEntity isolateMain) {
    jsAst.Expression mainAccess = _emitter.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); }',
        [_emitter.staticFunctionAccess(isolateMain), mainAccess]);
  }

  jsAst.Statement generateInvokeMain(FunctionEntity main) {
    jsAst.Expression mainCallClosure = null;
    if (_backendUsage.isIsolateInUse) {
      FunctionEntity isolateMain = _commonElements.startRootIsolate;
      mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
    } else {
      mainCallClosure = _emitter.staticFunctionAccess(main);
    }

    jsAst.Expression currentScriptAccess =
        _emitter.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
    });
  }
}
