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

final jsRuntimeBlobTemplate = Template(r'''
// Compiles a dart2wasm-generated main module from `source` which can then
// instantiatable via the `instantiate` method.
//
// `source` needs to be a `Response` object (or promise thereof) e.g. created
// via the `fetch()` JS API.
export async function compileStreaming(source) {
  const builtins = {<<BUILTINS_MAP_BODY>>};
  return new CompiledApp(
      await WebAssembly.compileStreaming(source, builtins), builtins);
}

// Compiles a dart2wasm-generated wasm modules from `bytes` which is then
// instantiatable via the `instantiate` method.
export async function compile(bytes) {
  const builtins = {<<BUILTINS_MAP_BODY>>};
  return new CompiledApp(await WebAssembly.compile(bytes, builtins), builtins);
}

// DEPRECATED: Please use `compile` or `compileStreaming` to get a compiled app,
// use `instantiate` method to get an instantiated app and then call
// `invokeMain` to invoke the main function.
export async function instantiate(modulePromise, importObjectPromise) {
  var moduleOrCompiledApp = await modulePromise;
  if (!(moduleOrCompiledApp instanceof CompiledApp)) {
    moduleOrCompiledApp = new CompiledApp(moduleOrCompiledApp);
  }
  const instantiatedApp = await moduleOrCompiledApp.instantiate(await importObjectPromise);
  return instantiatedApp.instantiatedModule;
}

// DEPRECATED: Please use `compile` or `compileStreaming` to get a compiled app,
// use `instantiate` method to get an instantiated app and then call
// `invokeMain` to invoke the main function.
export const invoke = (moduleInstance, ...args) => {
  moduleInstance.exports.$invokeMain(args);
}

class CompiledApp {
  constructor(module, builtins) {
    this.module = module;
    this.builtins = builtins;
  }

  // The second argument is an options object containing:
  // `loadDeferredModule` is a JS function that takes a module name matching a
  //   wasm file produced by the dart2wasm compiler and returns the bytes to
  //   load the module. These bytes can be in either a format supported by
  //   `WebAssembly.compile` or `WebAssembly.compileStreaming`.
  // `loadDynamicModule` is a JS function that takes two string names matching,
  //   in order, a wasm file produced by the dart2wasm compiler during dynamic
  //   module compilation and a corresponding js file produced by the same
  //   compilation. It should return a JS Array containing 2 elements. The first
  //   should be the bytes for the wasm module in a format supported by
  //   `WebAssembly.compile` or `WebAssembly.compileStreaming`. The second
  //   should be the result of using the JS 'import' API on the js file path.
  // `loadDeferredId` is a JS function that takes a string corresponding to a load
  //   ID generated by the compiler when 'load-ids' option is passed. Each load
  //   ID maps to one or more WASM modules produced by the compiler. This
  //   function should return an array of byte arrays corresponding to all the
  //   modules specified by that load ID. The arrays should be in a format
  //   supported by `WebAssembly.compile` or `WebAssembly.compileStreaming`.
  async instantiate(additionalImports,
      {loadDeferredModule, loadDynamicModule, loadDeferredId} = {}) {
    let dartInstance;

    // Prints to the console
    function printToConsole(value) {
      if (typeof dartPrint == "function") {
        dartPrint(value);
        return;
      }
      if (typeof console == "object" && typeof console.log != "undefined") {
        console.log(value);
        return;
      }
      if (typeof print == "function") {
        print(value);
        return;
      }

      throw "Unable to print message: " + value;
    }

    // A special symbol attached to functions that wrap Dart functions.
    const jsWrappedDartFunctionSymbol = Symbol("JSWrappedDartFunction");

    function finalizeWrapper(dartFunction, wrapped) {
      wrapped.dartFunction = dartFunction;
      wrapped[jsWrappedDartFunctionSymbol] = true;
      return wrapped;
    }

    // Imports
    const dart2wasm = {
      <<JS_METHODS>>
    };

    const baseImports = {
      dart2wasm: dart2wasm,
      Math: Math,
      Date: Date,
      Object: Object,
      Array: Array,
      Reflect: Reflect,
      <<IMPORTED_JS_STRINGS_IN_MJS>>
    };

    <<JS_STRING_POLYFILL_METHODS>>

    <<DEFERRED_LIBRARY_HELPER_METHODS>>

    dartInstance = await WebAssembly.instantiate(this.module, {
      ...baseImports,
      ...additionalImports,
      <<MODULE_LOADING_IMPORT>>
      <<JS_POLYFILL_IMPORT>>
    });

    return new InstantiatedApp(this, dartInstance);
  }
}

class InstantiatedApp {
  constructor(compiledApp, instantiatedModule) {
    this.compiledApp = compiledApp;
    this.instantiatedModule = instantiatedModule;
  }

  // Call the main function with the given arguments.
  invokeMain(...args) {
    this.instantiatedModule.exports.$invokeMain(args);
  }
}
''');

const String jsPolyFillMethods = r'''
const jsStringPolyfill = {
      "charCodeAt": (s, i) => s.charCodeAt(i),
      "compare": (s1, s2) => {
        if (s1 < s2) return -1;
        if (s1 > s2) return 1;
        return 0;
      },
      "concat": (s1, s2) => s1 + s2,
      "equals": (s1, s2) => s1 === s2,
      "fromCharCode": (i) => String.fromCharCode(i),
      "length": (s) => s.length,
      "substring": (s, a, b) => s.substring(a, b),
      "fromCharCodeArray": (a, start, end) => {
        if (end <= start) return '';

        const read = dartInstance.exports.$wasmI16ArrayGet;
        let result = '';
        let index = start;
        const chunkLength = Math.min(end - index, 500);
        let array = new Array(chunkLength);
        while (index < end) {
          const newChunkLength = Math.min(end - index, 500);
          for (let i = 0; i < newChunkLength; i++) {
            array[i] = read(a, index++);
          }
          if (newChunkLength < chunkLength) {
            array = array.slice(0, newChunkLength);
          }
          result += String.fromCharCode(...array);
        }
        return result;
      },
      "intoCharCodeArray": (s, a, start) => {
        if (s === '') return 0;

        const write = dartInstance.exports.$wasmI16ArraySet;
        for (var i = 0; i < s.length; ++i) {
          write(a, start++, s.charCodeAt(i));
        }
        return s.length;
      },
      "test": (s) => typeof s == "string",
    };
''';

final moduleLoadingHelperTemplate = Template(r'''
    const moduleLoadingHelper = {
      "loadDeferredModule": async (moduleName) => {
        if (!loadDeferredModule) {
          throw "No implementation of loadDeferredModule provided.";
        }
        const source = await Promise.resolve(loadDeferredModule(moduleName));
        const module = await ((source instanceof Response)
            ? WebAssembly.compileStreaming(source, this.builtins)
            : WebAssembly.compile(source, this.builtins));
        await WebAssembly.instantiate(module, {
          ...baseImports,
          ...additionalImports,
          <<JS_POLYFILL_IMPORT>>
          "module0": dartInstance.exports,
        });
      },
      "loadDeferredId": async (loadId) => {
        if (!loadDeferredId) {
          throw "No implementation of loadDeferredId provided.";
        }
        const sources = await Promise.resolve(loadDeferredId(loadId));
        for (const source of sources) {
          const module = await ((source instanceof Response)
              ? WebAssembly.compileStreaming(source, this.builtins)
              : WebAssembly.compile(source, this.builtins));
          await WebAssembly.instantiate(module, {
            ...baseImports,
            ...additionalImports,
            <<JS_POLYFILL_IMPORT>>
            "module0": dartInstance.exports,
          });
        }
      },
      "loadDynamicModuleFromUri": async (wasmUri, jsUri) => {
        if (!loadDynamicModule) {
          throw "No implementation of loadDynamicModule provided.";
        }
        const [source, jsModule] = await loadDynamicModule(wasmUri, jsUri);
        const module = await ((source instanceof Response)
            ? WebAssembly.compileStreaming(source, this.builtins)
            : WebAssembly.compile(source, this.builtins));
        const loadedModule = await WebAssembly.instantiate(module, {
          "module0": dartInstance.exports,
          ...jsModule.imports(finalizeWrapper),
        });
        return loadedModule.exports.$invokeEntryPoint;
      },
    };
''');

final dynamicSubmoduleJsImportTemplate = Template(r'''
export function imports(finalizeWrapper) {
  const dart2wasm = {
    <<JS_METHODS>>
  };

  return {
    dart2wasm: dart2wasm,
    <<IMPORTED_JS_STRINGS_IN_MJS>>
  };
}
''');

class Template {
  static final _templateVariableRegExp = RegExp(r'<<(?<varname>[A-Z_]+)>>');
  final List<_TemplatePart> _parts = [];

  Template(String stringTemplate) {
    int offset = 0;
    for (final match in _templateVariableRegExp.allMatches(stringTemplate)) {
      _parts.add(
          _TemplateStringPart(stringTemplate.substring(offset, match.start)));
      _parts.add(_TemplateVariablePart(match.namedGroup('varname')!));
      offset = match.end;
    }
    _parts.add(_TemplateStringPart(
        stringTemplate.substring(offset, stringTemplate.length)));
  }

  String instantiate(Map<String, String> variableValues) {
    final sb = StringBuffer();
    for (final part in _parts) {
      sb.write(part.instantiate(variableValues));
    }
    return sb.toString();
  }
}

abstract class _TemplatePart {
  String instantiate(Map<String, String> variableValues);
}

class _TemplateStringPart extends _TemplatePart {
  final String string;
  _TemplateStringPart(this.string);

  @override
  String instantiate(Map<String, String> variableValues) => string;
}

class _TemplateVariablePart extends _TemplatePart {
  final String variable;
  _TemplateVariablePart(this.variable);

  @override
  String instantiate(Map<String, String> variableValues) {
    final value = variableValues[variable];
    if (value != null) return value;
    throw 'Template contains no value for variable $variable';
  }
}
