from pathlib import Path
import shutil
import re


def sub_file(in_path, out_path, reg_exp_repls):
    with open(in_path, "r") as fin:
        text = fin.read()
    for reg_exp, repl in reg_exp_repls:
        text = re.sub(reg_exp, repl, text)
    with open(out_path, "w") as fout:
        fout.write(text)


patched_ts = r"""interface GrowableTypes {
  GROWABLE_HEAP_U8(): Uint8Array;
  GROWABLE_HEAP_U16(): Uint16Array;
  GROWABLE_HEAP_U32(): Uint32Array;
  GROWABLE_HEAP_F32(): Float32Array;
  GROWABLE_HEAP_F64(): Float64Array;
  GROWABLE_HEAP_I8(): Int8Array;
  GROWABLE_HEAP_I16(): Int16Array;
  GROWABLE_HEAP_I32(): Int32Array;
}

export type MainModule = \g<1> & GrowableTypes;
"""


def main(source_dir, bin_dir):
    source_dir = Path(source_dir)
    bin_dir = Path(bin_dir)
    artifacts_dir = source_dir / "artifacts"
    artifacts_dir.mkdir(exist_ok=True)
    for f in ("dsp-engine.wasm", "dsp-engine.aw.js"):
        shutil.copyfile(bin_dir / f, artifacts_dir / f)
    shutil.copyfile(
        source_dir / "dsp-engine.ww.js_PATCHED", artifacts_dir / "dsp-engine.ww.js"
    )
    sub_file(
        bin_dir / "dsp-engine.js",
        artifacts_dir / "dsp-engine.js",
        [
            (r"new Worker\([^)]*locateFile\([^)]*\)", r'\g<0>, { "type": "module" }'),
            (
                r"(new Worker\([^)]*)(locateFile\([^)]*\))",
                r"\g<1>/* turbopackIgnore: true */\g<2>",
            ),
            (r'"dsp-engine.aw.js"', r"/* turbopackIgnore: true */locateFile(\g<0>)"),
            (
                r"createRequire\(import\.meta\.url\)",
                'createRequire(import.meta.url === undefined ? "/dev/null/doesnotexist" : import.meta.url)',
            ),
            (
                r"\!import\.meta\.url\.startsWith",
                "import.meta.url !== undefined && !import.meta.url.startsWith",
            ),
            (
                r"async function getWasmBinary\s*\(([^)]*)\)\s*{([^}]*)\s+readAsync\(",
                r"async function getWasmBinary(\g<1>){\g<2> (async(x)=>{if(ENVIRONMENT_IS_NODE){var sea=require('node:sea');if(sea.isSea()){return new Uint8Array(sea.getAsset(binaryFile))}}return await readAsync(x);})(",
            ),
        ],
    )
    ts_path = bin_dir / "dsp-engine.d.ts"
    ts_out_path = artifacts_dir / "dsp-engine.d.ts"
    if ts_path.exists():
        sub_file(
            ts_path, ts_out_path, [(r"export type MainModule = (.*);", patched_ts)]
        )
    elif ts_out_path.exists():
        ts_out_path.unlink()


if __name__ == "__main__":
    import sys

    main(sys.argv[1], sys.argv[2])
