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

/* <GEN_DOC> */

import 'dart:async';
import 'dart:convert';
import 'dart:ffi';
import 'dart:io';
import 'dart:typed_data';
import 'package:ffi/ffi.dart';
import 'wasmer_api.dart';

class WasmImportDescriptor {
  int kind;
  String moduleName;
  String name;
  Pointer<WasmerFunctype> funcType;
  WasmImportDescriptor(this.kind, this.moduleName, this.name, this.funcType);

  String toString() {
    var kindName = wasmerExternKindName(kind);
    if (kind == WasmerExternKindFunction) {
      var runtime = WasmRuntime();
      var sig = WasmRuntime.getSignatureString("${moduleName}::${name}",
          runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
      return "$kindName: $sig";
    } else {
      return "$kindName: ${moduleName}::${name}";
    }
  }
}

class WasmExportDescriptor {
  int kind;
  String name;
  Pointer<WasmerFunctype> funcType;
  WasmExportDescriptor(this.kind, this.name, this.funcType);

  String toString() {
    var kindName = wasmerExternKindName(kind);
    if (kind == WasmerExternKindFunction) {
      var runtime = WasmRuntime();
      var sig = WasmRuntime.getSignatureString(
          name, runtime.getArgTypes(funcType), runtime.getReturnType(funcType));
      return "$kindName: $sig";
    } else {
      return "$kindName: ${name}";
    }
  }
}

class _WasmTrapsEntry {
  dynamic exception;
  _WasmTrapsEntry(this.exception);
}

class WasmRuntime {
  static WasmRuntime? _inst;

  DynamicLibrary _lib;
  late Pointer<WasmerEngine> _engine;
  Map<int, _WasmTrapsEntry> traps = {};
/* <RUNTIME_MEMB> */

  factory WasmRuntime() {
    return _inst ??= WasmRuntime._init();
  }

  static String _getLibName() {
    if (Platform.isMacOS) return "libwasmer.dylib";
    if (Platform.isLinux) return "libwasmer.so";
    // TODO(dartbug.com/37882): Support more platforms.
    throw Exception("Wasm not currently supported on this platform");
  }

  static String? _getLibPathFrom(Uri root) {
    // The dynamic library created by pub run wasm:setup is located relative to
    // the package_config.json file, so walk up from the script directory until
    // we find it.
    do {
      if (File.fromUri(root.resolve('.dart_tool/package_config.json'))
          .existsSync()) {
        return root.resolve('.dart_tool/wasm/' + _getLibName()).path;
      }
    } while (root != (root = root.resolve('..')));
    return null;
  }

  static String _getLibPath() {
    var path = _getLibPathFrom(Platform.script.resolve('./'));
    if (path != null) return path;
    path = _getLibPathFrom(Directory.current.uri);
    if (path != null) return path;
    throw Exception("Wasm library not found. Did you `pub run wasm:setup`?");
  }

  WasmRuntime._init() : _lib = DynamicLibrary.open(_getLibPath()) {
/* <RUNTIME_LOAD> */

    if (_Dart_InitializeApiDL(NativeApi.initializeApiDLData) != 0) {
      throw Exception("Failed to initialize Dart API");
    }
    _engine = _engine_new();
    _checkNotEqual(_engine, nullptr, "Failed to initialize Wasm engine.");
    _set_finalizer_for_engine(this, _engine);
  }

  Pointer<WasmerStore> newStore(Object owner) {
    Pointer<WasmerStore> store = _checkNotEqual(
        _store_new(_engine), nullptr, "Failed to create Wasm store.");
    _set_finalizer_for_store(owner, store);
    return store;
  }

  Pointer<WasmerModule> compile(
      Object owner, Pointer<WasmerStore> store, Uint8List data) {
    var dataPtr = calloc<Uint8>(data.length);
    for (int i = 0; i < data.length; ++i) {
      dataPtr[i] = data[i];
    }
    var dataVec = calloc<WasmerByteVec>();
    dataVec.ref.data = dataPtr;
    dataVec.ref.length = data.length;

    var modulePtr = _module_new(store, dataVec);

    calloc.free(dataPtr);
    calloc.free(dataVec);

    _checkNotEqual(modulePtr, nullptr, "Wasm module compile failed.");
    _set_finalizer_for_module(owner, modulePtr);
    return modulePtr;
  }

  List<WasmExportDescriptor> exportDescriptors(Pointer<WasmerModule> module) {
    var exportsVec = calloc<WasmerExporttypeVec>();
    _module_exports(module, exportsVec);
    var exps = <WasmExportDescriptor>[];
    for (var i = 0; i < exportsVec.ref.length; ++i) {
      var exp = exportsVec.ref.data[i];
      var extern = _exporttype_type(exp);
      var kind = _externtype_kind(extern);
      var fnType = kind == WasmerExternKindFunction
          ? _externtype_as_functype(extern)
          : nullptr;
      exps.add(WasmExportDescriptor(
          kind, _exporttype_name(exp).ref.toString(), fnType));
    }
    calloc.free(exportsVec);
    return exps;
  }

  List<WasmImportDescriptor> importDescriptors(Pointer<WasmerModule> module) {
    var importsVec = calloc<WasmerImporttypeVec>();
    _module_imports(module, importsVec);
    var imps = <WasmImportDescriptor>[];
    for (var i = 0; i < importsVec.ref.length; ++i) {
      var imp = importsVec.ref.data[i];
      var extern = _importtype_type(imp);
      var kind = _externtype_kind(extern);
      var fnType = kind == WasmerExternKindFunction
          ? _externtype_as_functype(extern)
          : nullptr;
      imps.add(WasmImportDescriptor(
          kind,
          _importtype_module(imp).ref.toString(),
          _importtype_name(imp).ref.toString(),
          fnType));
    }
    calloc.free(importsVec);
    return imps;
  }

  void maybeThrowTrap(Pointer<WasmerTrap> trap, String source) {
    if (trap != nullptr) {
      // There are 2 kinds of trap, and their memory is managed differently.
      // Traps created in the newTrap method below are stored in the traps map
      // with a corresponding exception, and their memory is managed using a
      // finalizer on the _WasmTrapsEntry. Traps can also be created by WASM
      // code, and in that case we delete them in this function.
      var entry = traps[trap.address];
      if (entry != null) {
        traps.remove(entry);
        throw entry.exception;
      } else {
        var trapMessage = calloc<WasmerByteVec>();
        _trap_message(trap, trapMessage);
        var message = "Wasm trap when calling $source: ${trapMessage.ref}";
        _byte_vec_delete(trapMessage);
        calloc.free(trapMessage);
        _trap_delete(trap);
        throw Exception(message);
      }
    }
  }

  Pointer<WasmerInstance> instantiate(Object owner, Pointer<WasmerStore> store,
      Pointer<WasmerModule> module, Pointer<WasmerExternVec> imports) {
    var trap = calloc<Pointer<WasmerTrap>>();
    trap.value = nullptr;
    var inst = _instance_new(store, module, imports, trap);
    maybeThrowTrap(trap.value, "module initialization function");
    calloc.free(trap);
    _checkNotEqual(inst, nullptr, "Wasm module instantiation failed.");
    _set_finalizer_for_instance(owner, inst);
    return inst;
  }

  // Clean up the exports after use, with deleteExports.
  Pointer<WasmerExternVec> exports(Pointer<WasmerInstance> instancePtr) {
    var exports = calloc<WasmerExternVec>();
    _instance_exports(instancePtr, exports);
    return exports;
  }

  void deleteExports(Pointer<WasmerExternVec> exports) {
    _extern_vec_delete(exports);
    calloc.free(exports);
  }

  int externKind(Pointer<WasmerExtern> extern) {
    return _extern_kind(extern);
  }

  Pointer<WasmerFunc> externToFunction(Pointer<WasmerExtern> extern) {
    return _extern_as_func(extern);
  }

  Pointer<WasmerExtern> functionToExtern(Pointer<WasmerFunc> func) {
    return _func_as_extern(func);
  }

  List<int> getArgTypes(Pointer<WasmerFunctype> funcType) {
    var types = <int>[];
    var args = _functype_params(funcType);
    for (var i = 0; i < args.ref.length; ++i) {
      types.add(_valtype_kind(args.ref.data[i]));
    }
    return types;
  }

  int getReturnType(Pointer<WasmerFunctype> funcType) {
    var rets = _functype_results(funcType);
    if (rets.ref.length == 0) {
      return WasmerValKindVoid;
    } else if (rets.ref.length > 1) {
      throw Exception("Multiple return values are not supported");
    }
    return _valtype_kind(rets.ref.data[0]);
  }

  void call(Pointer<WasmerFunc> func, Pointer<WasmerValVec> args,
      Pointer<WasmerValVec> results, String source) {
    maybeThrowTrap(_func_call(func, args, results), source);
  }

  Pointer<WasmerMemory> externToMemory(Pointer<WasmerExtern> extern) {
    return _extern_as_memory(extern);
  }

  Pointer<WasmerExtern> memoryToExtern(Pointer<WasmerMemory> memory) {
    return _memory_as_extern(memory);
  }

  Pointer<WasmerMemory> newMemory(
      Object owner, Pointer<WasmerStore> store, int pages, int? maxPages) {
    var limPtr = calloc<WasmerLimits>();
    limPtr.ref.min = pages;
    limPtr.ref.max = maxPages ?? wasm_limits_max_default;
    var memType = _memorytype_new(limPtr);
    calloc.free(limPtr);
    _checkNotEqual(memType, nullptr, "Failed to create memory type.");
    _set_finalizer_for_memorytype(owner, memType);
    var memory = _checkNotEqual(
        _memory_new(store, memType), nullptr, "Failed to create memory.");
    _set_finalizer_for_memory(owner, memory);
    return memory;
  }

  void growMemory(Pointer<WasmerMemory> memory, int deltaPages) {
    _checkNotEqual(
        _memory_grow(memory, deltaPages), 0, "Failed to grow memory.");
  }

  int memoryLength(Pointer<WasmerMemory> memory) {
    return _memory_size(memory);
  }

  Uint8List memoryView(Pointer<WasmerMemory> memory) {
    return _memory_data(memory).asTypedList(_memory_data_size(memory));
  }

  Pointer<WasmerFunc> newFunc(
      Object owner,
      Pointer<WasmerStore> store,
      Pointer<WasmerFunctype> funcType,
      Pointer func,
      Pointer env,
      Pointer finalizer) {
    var f = _func_new_with_env(
        store, funcType, func.cast(), env.cast(), finalizer.cast());
    _checkNotEqual(f, nullptr, "Failed to create function.");
    _set_finalizer_for_func(owner, f);
    return f;
  }

  Pointer<WasmerTrap> newTrap(Pointer<WasmerStore> store, dynamic exception) {
    var msg = calloc<WasmerByteVec>();
    msg.ref.data = calloc<Uint8>();
    msg.ref.data[0] = 0;
    msg.ref.length = 0;
    var trap = _trap_new(store, msg);
    calloc.free(msg.ref.data);
    calloc.free(msg);
    _checkNotEqual(trap, nullptr, "Failed to create trap.");
    var entry = _WasmTrapsEntry(exception);
    _set_finalizer_for_trap(entry, trap);
    traps[trap.address] = entry;
    return trap;
  }

  Pointer<WasmerWasiConfig> newWasiConfig() {
    var name = calloc<Uint8>();
    name[0] = 0;
    var config = _wasi_config_new(name);
    calloc.free(name);
    return _checkNotEqual(config, nullptr, "Failed to create WASI config.");
  }

  void captureWasiStdout(Pointer<WasmerWasiConfig> config) {
    _wasi_config_inherit_stdout(config);
  }

  void captureWasiStderr(Pointer<WasmerWasiConfig> config) {
    _wasi_config_inherit_stderr(config);
  }

  Pointer<WasmerWasiEnv> newWasiEnv(Pointer<WasmerWasiConfig> config) {
    return _checkNotEqual(
        _wasi_env_new(config), nullptr, "Failed to create WASI environment.");
  }

  void wasiEnvSetMemory(
      Pointer<WasmerWasiEnv> env, Pointer<WasmerMemory> memory) {
    _wasi_env_set_memory(env, memory);
  }

  void getWasiImports(Pointer<WasmerStore> store, Pointer<WasmerModule> mod,
      Pointer<WasmerWasiEnv> env, Pointer<WasmerExternVec> imports) {
    _checkNotEqual(_wasi_get_imports(store, mod, env, imports), 0,
        "Failed to fill WASI imports.");
  }

  Stream<List<int>> getWasiStdoutStream(Pointer<WasmerWasiEnv> env) {
    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stdout));
  }

  Stream<List<int>> getWasiStderrStream(Pointer<WasmerWasiEnv> env) {
    return Stream.fromIterable(_WasiStreamIterable(env, _wasi_env_read_stderr));
  }

  String _getLastError() {
    var length = _wasmer_last_error_length();
    var buf = calloc<Uint8>(length);
    _wasmer_last_error_message(buf, length);
    String message = utf8.decode(buf.asTypedList(length));
    calloc.free(buf);
    return message;
  }

  T _checkNotEqual<T>(T x, T y, String errorMessage) {
    if (x == y) {
      throw Exception("$errorMessage\n${_getLastError()}");
    }
    return x;
  }

  static String getSignatureString(
      String name, List<int> argTypes, int returnType) {
    return "${wasmerValKindName(returnType)} $name" +
        "(${argTypes.map(wasmerValKindName).join(", ")})";
  }
}

class _WasiStreamIterator implements Iterator<List<int>> {
  static final int _bufferLength = 1024;
  Pointer<WasmerWasiEnv> _env;
  Function _reader;
  Pointer<Uint8> _buf = calloc<Uint8>(_bufferLength);
  int _length = 0;
  _WasiStreamIterator(this._env, this._reader) {}

  bool moveNext() {
    _length = _reader(_env, _buf, _bufferLength);
    return true;
  }

  List<int> get current => _buf.asTypedList(_length);
}

class _WasiStreamIterable extends Iterable<List<int>> {
  Pointer<WasmerWasiEnv> _env;
  Function _reader;
  _WasiStreamIterable(this._env, this._reader) {}
  @override
  Iterator<List<int>> get iterator => _WasiStreamIterator(_env, _reader);
}
