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

// Note: this is a copy from flutter tools, updated to work with dwds tests

/// JavaScript snippet to determine the base URL of the current path.
const String _baseUrlScript = '''
var baseUrl = (function () {
  // Attempt to detect --precompiled mode for tests, and set the base url
  // appropriately, otherwise set it to '/'.
  var pathParts = location.pathname.split("/");
  if (pathParts[0] == "") {
    pathParts.shift();
  }
  if (pathParts.length > 1 && pathParts[1] == "test") {
    return "/" + pathParts.slice(0, 2).join("/") + "/";
  }
  // Attempt to detect base url using <base href> html tag
  // base href should start and end with "/"
  if (typeof document !== 'undefined') {
    var el = document.getElementsByTagName('base');
    if (el && el[0] && el[0].getAttribute("href") && el[0].getAttribute
    ("href").startsWith("/") && el[0].getAttribute("href").endsWith("/")){
      return el[0].getAttribute("href");
    }
  }
  // return default value
  return "/";
}());
var _trimmedBaseUrl = baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl;
var _currentDirectory = window.location.origin + _trimmedBaseUrl;
''';

/// Used to load prerequisite scripts such as ddc_module_loader.js
const String _simpleLoaderScript = r'''
window.$dartCreateScript = (function() {
  // Find the nonce value. (Note, this is only computed once.)
  var scripts = Array.from(document.getElementsByTagName("script"));
  var nonce;
  scripts.some(
      script => (nonce = script.nonce || script.getAttribute("nonce")));
  // If present, return a closure that automatically appends the nonce.
  if (nonce) {
    return function() {
      var script = document.createElement("script");
      script.nonce = nonce;
      return script;
    };
  } else {
    return function() {
      return document.createElement("script");
    };
  }
})();

// Loads a module [relativeUrl] relative to [root].
//
// If not specified, [root] defaults to the directory serving the main app.
var forceLoadModule = function (relativeUrl, root) {
  var actualRoot = root ?? _currentDirectory;
  var trimmedRoot = actualRoot.endsWith('/') ? actualRoot.substring(0, actualRoot.length - 1) : actualRoot;
  return new Promise(function(resolve, reject) {
    var script = self.$dartCreateScript();
    let policy = {
      createScriptURL: function(src) {return src;}
    };
    if (self.trustedTypes && self.trustedTypes.createPolicy) {
      policy = self.trustedTypes.createPolicy('dartDdcModuleUrl', policy);
    }
    script.onload = resolve;
    script.onerror = reject;
    script.src = policy.createScriptURL(trimmedRoot + "/" + relativeUrl);
    document.head.appendChild(script);
  });
};
''';

/// The JavaScript bootstrap script to support in-browser hot restart.
///
/// The [requireUrl] loads our cached RequireJS script file. The [mapperUrl]
/// loads the special Dart stack trace mapper. The [entrypoint] is the
/// actual main.dart file.
///
/// This file is served when the browser requests "main.dart.js" in debug mode,
/// and is responsible for bootstrapping the RequireJS modules and attaching
/// the hot reload hooks.
String generateBootstrapScript({
  required String requireUrl,
  required String mapperUrl,
  required String entrypoint,
}) {
  return '''
"use strict";

// Attach source mapping.
var mapperEl = document.createElement("script");
mapperEl.defer = true;
mapperEl.async = false;
mapperEl.src = "$mapperUrl";
document.head.appendChild(mapperEl);

// Attach require JS.
var requireEl = document.createElement("script");
requireEl.defer = true;
requireEl.async = false;
requireEl.src = "$requireUrl";
// This attribute tells require JS what to load as main (defined below).
requireEl.setAttribute("data-main", "main_module.bootstrap");
document.head.appendChild(requireEl);
''';
}

/// Generate a synthetic main module which captures the application's main
/// method.
///
/// RE: Object.keys usage in app.main:
/// This attaches the main entrypoint and hot reload functionality to the window.
/// The app module will have a single property which contains the actual application
/// code. The property name is based off of the entrypoint that is generated, for example
/// the file `foo/bar/baz.dart` will generate a property named approximately
/// `foo__bar__baz`. Rather than attempt to guess, we assume the first property of
/// this object is the module.
String generateMainModule({required String entrypoint}) {
  return '''/* ENTRYPOINT_EXTENTION_MARKER */

// Create the main module loaded below.
define("main_module.bootstrap", ["$entrypoint", "dart_sdk"], function(app, dart_sdk) {
  dart_sdk.dart.setStartAsyncSynchronously(true);
  dart_sdk._isolate_helper.startRootIsolate(() => {}, []);
  dart_sdk._debugger.registerDevtoolsFormatter();
  let voidToNull = () => (voidToNull = dart_sdk.dart.constFn(dart_sdk.dart.fnType(dart_sdk.core.Null, [dart_sdk.dart.void])))();

  // See the generateMainModule doc comment.
  var child = {};
  child.main = app[Object.keys(app)[0]].main;

  /* MAIN_EXTENSION_MARKER */
  child.main();
});
''';
}

String generateDDCBootstrapScript({
  required String ddcModuleLoaderUrl,
  required String mapperUrl,
  required String entrypoint,
  required String bootstrapUrl,
}) {
  return '''
$_baseUrlScript
$_simpleLoaderScript

(function() {
  let appName = "$entrypoint";

  // A uuid that identifies a subapp.
  let uuid = "00000000-0000-0000-0000-000000000000";

  window.postMessage(
      {type: "DDC_STATE_CHANGE", state: "initial_load", targetUuid: uuid}, "*");

  // Load pre-requisite DDC scripts. We intentionally use invalid names to avoid namespace clashes.
  let prerequisiteScripts = [
    {
      "src": "$ddcModuleLoaderUrl",
      "id": "dart_library \x00"
    },
    {
      "src": "$mapperUrl",
      "id": "dart_stack_trace_mapper \x00"
    }
  ];

  // Load ddc_module_loader.js to access DDC's module loader API.
  let prerequisiteLoads = [];
  for (let i = 0; i < prerequisiteScripts.length; i++) {
    prerequisiteLoads.push(forceLoadModule(prerequisiteScripts[i].src));
  }
  Promise.all(prerequisiteLoads).then((_) => afterPrerequisiteLogic());
 
  // Save the current script so we can access it in a closure.
  var _currentScript = document.currentScript;

  var afterPrerequisiteLogic = function() {
    window.\$dartLoader.rootDirectories.push(_currentDirectory);
    let scripts = [
      {
        "src": "dart_sdk.js",
        "id": "dart_sdk"
      },
      {
        "src": "$bootstrapUrl",
        "id": "data-main"
      }
    ];
    let loadConfig = new window.\$dartLoader.LoadConfiguration();
    loadConfig.root = _currentDirectory;
    loadConfig.bootstrapScript = scripts[scripts.length - 1];

    if (window.\$dartJITModules) {
      loadConfig.loadScriptFn = function(loader) {
        // Loads just the entrypoint module and required SDK modules.
        let moduleSet = new Set();
        // This cache is populated by ddc_module_loader.js
        let libraryCache = JSON.parse(window.localStorage.getItem(`dartLibraryCache:\${appName}`));
        if (libraryCache) {
          // TODO(b/165021238) - when should this be invalidated?
          moduleSet = new Set(libraryCache["modules"])
        }
        loader.addScriptsToQueue(scripts, function(script) {
            // Preemptively load the ddc module loader and previously executed modules.
            return moduleSet.size == 0
                  || script.id.includes("dart_library")
                  // We preemptively load the stack_trace_mapper module so that we can
                  // translate JS errors to Dart.
                  || script.id.includes("stack_trace_mapper")
                  || moduleSet.has(script.id);
        });
        loader.loadEnqueuedModules();
      }
      loadConfig.ddcEventForLoadStart = /* LOAD_ENTRYPOINT_MODULES_START */ 4;
      loadConfig.ddcEventForLoadedOk = /* LOAD_ENTRYPOINT_MODULES_END_OK */ 5;
      loadConfig.ddcEventForLoadedError = /* LOAD_ENTRYPOINT_MODULES_END_ERROR */ 6;
    } else {
      loadConfig.loadScriptFn = function(loader) {
        loader.addScriptsToQueue(scripts, null);
        loader.loadEnqueuedModules();
      }
      loadConfig.ddcEventForLoadStart = /* LOAD_ALL_MODULES_START */ 1;
      loadConfig.ddcEventForLoadedOk = /* LOAD_ALL_MODULES_END_OK */ 2;
      loadConfig.ddcEventForLoadedError = /* LOAD_ALL_MODULES_END_ERROR */ 3;
    }

    let loader = new window.\$dartLoader.DDCLoader(loadConfig);

    // Record prerequisite scripts' fully resolved URLs.
    prerequisiteScripts.forEach(script => loader.registerScript(script));

    // Note: these variables should only be used in non-multi-app scenarios since
    // they can be arbitrarily overridden based on multi-app load order.
    window.\$dartLoader.loadConfig = loadConfig;
    window.\$dartLoader.loader = loader;
    loader.nextAttempt();

    let currentUri = _currentScript.src;
    let fetchEtagsUri;
    if (currentUri.indexOf("?") == -1) {
      fetchEtagsUri = currentUri + "?fetch-etags=true";
    } else {
      fetchEtagsUri = currentUri + "&fetch-etags=true";
    }

    if (!window.\$dartAppNameToMetadata) {
      window.\$dartAppNameToMetadata = new Map();
    }
    window.\$dartAppNameToMetadata.set(appName, {
        currentDirectory: _currentDirectory,
        currentUri: currentUri,
        fetchEtagsUri: fetchEtagsUri,
    });

    if (!window.\$dartReloadModifiedModules) {
      window.\$dartReloadModifiedModules = (function(appName, callback) {
        function cb() {
          window.postMessage(
              {
                type: "DDC_STATE_CHANGE",
                state: "restart_end",
                targetUuid: uuid,
              },
              "*");
          callback();
        }
        window.postMessage(
            {
              type: "DDC_STATE_CHANGE",
              state: "restart_begin",
              targetUuid: uuid,
            },
            "*");
        var xhttp = new XMLHttpRequest();
        xhttp.withCredentials = true;
        xhttp.onreadystatechange = function() {
          // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/readyState
          if (this.readyState == 4 && this.status == 200 || this.status == 304) {
            var scripts = JSON.parse(this.responseText);
            var numToLoad = 0;
            var numLoaded = 0;
            for (var i = 0; i < scripts.length; i++) {
              var script = scripts[i];
              if (script.id == null) continue;
              var src =
                  window.\$dartAppNameToMetadata.get(appName).currentDirectory +
                  script.src.toString();
              var oldSrc = window.\$dartLoader.moduleIdToUrl.get(script.id);
              // Only compare the search parameters which contain the cache
              // busting portion of the uri. The path might be different if the
              // script is loaded from a different application on the page.
              if (new URL(oldSrc).search == new URL(src).search) continue;

              // We might actually load from a different uri, delete the old one
              // just to be sure.
              window.\$dartLoader.urlToModuleId.delete(oldSrc);

              window.\$dartLoader.moduleIdToUrl.set(script.id, src);
              window.\$dartLoader.urlToModuleId.set(src, script.id);

              if (window.\$dartJITModules) {
              // Simply invalidate the import and the corresponding module will
              // be lazily loaded.
              dart_library.invalidateImport(script.id);
              continue;
              } else {
                numToLoad++;
              }

              var el = document.getElementById(script.id);
              if (el) el.remove();
              el = window.\$dartCreateScript();
              el.src = policy.createScriptURL(src);
              el.async = false;
              el.defer = true;
              el.id = script.id;
              el.onload = function() {
                numLoaded++;
                if (numToLoad == numLoaded) cb();
              };
              document.head.appendChild(el);
            }
            // Call `cb` right away if we found no updated scripts.
            if (numToLoad == 0) cb();
          }
        };
        xhttp.open("GET",
          window.\$dartAppNameToMetadata.get(appName).fetchEtagsUri, true);
        let sdk = dart_library.import("dart_sdk", appName);
        let developer = sdk.developer;
        if (developer._extensions.containsKey("ext.flutter.disassemble")) {
          developer.invokeExtension("ext.flutter.disassemble", "{}").then(() => {
            // TODO(b/204210914): we should really be clearing all statics for all
            // apps, but for now we just do it for flutter apps which we recognize
            // based on this extension.
            sdk.dart.hotRestart();
            xhttp.send();
          });
        } else {
          xhttp.send();
        }
      });
    }
  }
})();
''';
}

String generateDDCMainModule(
    {required String entrypoint, String? exportedMain}) {
  final exportedMainName = exportedMain ?? entrypoint.split('.')[0];
  return '''/* ENTRYPOINT_EXTENTION_MARKER */

(function() {
  let appName = "$entrypoint";

  // A uuid that identifies a subapp.
  let uuid = "00000000-0000-0000-0000-000000000000";

  let dart_sdk = dart_library.import('dart_sdk', appName);

  dart_sdk.dart.setStartAsyncSynchronously(true);
  dart_sdk._debugger.registerDevtoolsFormatter();
  dart_sdk._isolate_helper.startRootIsolate(() => {}, []);

  let child = {};
  child.main = function() {
    dart_library.start(appName, uuid, "$entrypoint", "$exportedMainName");
  }

  /* MAIN_EXTENSION_MARKER */
  child.main();
})();
''';
}
