// Copyright 2024 the V8 project authors. All rights reserved.
// Copyright 2025 Apple Inc. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// First, some polyfills for missing browser APIs in JavaScript shells.
// Since the generated JavaScript code of SQLite immediately uses some of them,
// we need to load and run this code before the generated `speedtest1.js` in the
// JetStream driver.

// Empty `URLSearchParams` has just the same interface as a `Map`.
globalThis.URLSearchParams = Map;

// `TextEncoder` and `TextDecoder`. These are called only a few times with short
// ASCII strings, so this is sufficient and not performance-critical.
class TextEncoder {
  encode(string) {
    return Uint8Array.from(string, (char) => {
      let byte = char.codePointAt(0);
      if (byte > 0x7f)
        throw new Error("TextEncoder polyfill only supports ASCII");
      return byte;
    });
  }
}
class TextDecoder {
  decode(array) {
    for (let byte of array) {
      if (byte > 0x7f)
        throw new Error("TextDecoder polyfill only supports ASCII");
    }
    return String.fromCharCode.apply(null, array);
  }
}

// Now, some configuration options for when we initialize SQLite.

// Use JetStream functions instead of `console.log` and friends.
globalThis.sqlite3ApiConfig = {
  log: print,
  debug: print,
  warn: print,
  error: print,
};

// Make sure we never initialize OPFS by removing one of it's APIs (see
// `installOpfsVfs` in the generated JavaScript code of sqlite).
// We never want to use it anyway (see VFS config below) and this way we don't
// waste cycles on the browser runner to initialize it.
delete globalThis.FileSystemHandle;

class Benchmark {
  sqlite3Module;

  async init() {
    Module.wasmBinary = await getBinary(wasmBinary);
  }

  async runIteration() {
    if (!this.sqlite3Module) {
      // Defined in the generated SQLite JavaScript code.
      // Different in details but seemingly related/inspired by Emscripten code.
      this.sqlite3Module = await sqlite3InitModule(Module);
    }

    // The following is simplified from inline JavaScript in `speedtest1.html`.
    
    // Configure the VFS to use.
    // Don't use OPFS, WASMFS (which is on top of OPFS), or kvvfs, since they
    // all use persistent browser storage (localStorage or OPFS), which is not
    // available in JavaScript shells.
    // Also don't use memfs, since that crashes with a NULL function pointer.
    // Instead, make the default VFS explicit.
    const capi = this.sqlite3Module.capi
    print("Available SQLite VFS:", capi.sqlite3_js_vfs_list());
    const vfs = "unix";
    print("Using VFS:", vfs);
    const pVfs = capi.sqlite3_vfs_find(vfs);
    if (!pVfs) {
      throw new Error("Unknown VFS:", vfs);
    }

    // These arguments should match the upstream browser runner in 
    // `speedtest1.html`, except for the --size parameter.
    let argv = [
      "speedtest1",
      "--singlethread",
      //"--nomutex",
      //"--nosync",
      //"--memdb", // note that memdb trumps the filename arg
      "--nomemstat",
      "--big-transactions" /*important for tests 410 and 510!*/,
      "--size", "2", // To speedup, default is 100 (and takes about 4s).
      "--vfs", vfs, // See VFS comment above.
    ];

    print("Calling main with argv:", argv);
    const wasm = this.sqlite3Module.wasm;
    wasm.scopedAllocPush();  // Required for `scopedAllocMainArgv()`.
    wasm.xCall("wasm_main", argv.length, wasm.scopedAllocMainArgv(argv));
    wasm.scopedAllocPop();
  }
}
