//! Disassembly calling function for `wasm32` targets.
use wasm_bindgen::prelude::*;

use crate::Function;
use std::collections::HashSet;

#[wasm_bindgen(module = "child_process")]
extern "C" {
    #[wasm_bindgen(js_name = execFileSync)]
    fn exec_file_sync(cmd: &str, args: &js_sys::Array, opts: &js_sys::Object) -> Buffer;
}

#[wasm_bindgen(module = "buffer")]
extern "C" {
    type Buffer;
    #[wasm_bindgen(method, js_name = toString)]
    fn to_string(this: &Buffer) -> String;
}

#[wasm_bindgen]
extern "C" {
    #[wasm_bindgen(js_namespace = require)]
    fn resolve(module: &str) -> String;
    #[wasm_bindgen(js_namespace = console, js_name = log)]
    pub fn js_console_log(s: &str);
}

pub(crate) fn disassemble_myself() -> HashSet<Function> {
    use std::path::Path;
    ::console_error_panic_hook::set_once();
    // Our wasm module in the wasm-bindgen test harness is called
    // "wasm-bindgen-test_bg". When running in node this is actually a shim JS
    // file. Ask node where that JS file is, and then we use that with a wasm
    // extension to find the wasm file itself.
    let js_shim = resolve("wasm-bindgen-test_bg");
    let js_shim = Path::new(&js_shim).with_extension("wasm");

    // Execute `wasm2wat` synchronously, waiting for and capturing all of its
    // output. Note that we pass in a custom `maxBuffer` parameter because we're
    // generating a ton of output that needs to be buffered.
    let args = js_sys::Array::new();
    args.push(&js_shim.display().to_string().into());
    args.push(&"--enable-simd".into());
    let opts = js_sys::Object::new();
    js_sys::Reflect::set(&opts, &"maxBuffer".into(), &(200 * 1024 * 1024).into()).unwrap();
    let output = exec_file_sync("wasm2wat", &args, &opts).to_string();

    let mut ret: HashSet<Function> = HashSet::new();
    let mut lines = output.lines().map(|s| s.trim());
    while let Some(line) = lines.next() {
        // If this isn't a function, we don't care about it.
        if !line.starts_with("(func ") {
            continue;
        }

        let mut function = Function {
            name: String::new(),
            instrs: Vec::new(),
        };

        // Empty functions will end in `))` so there's nothing to do, otherwise
        // we'll have a bunch of following lines which are instructions.
        //
        // Lines that have an imbalanced `)` mark the end of a function.
        if !line.ends_with("))") {
            while let Some(line) = lines.next() {
                function.instrs.push(line.to_string());
                if !line.starts_with("(") && line.ends_with(")") {
                    break;
                }
            }
        }
        // The second element here split on whitespace should be the name of
        // the function, skipping the type/params/results
        function.name = line.split_whitespace().nth(1).unwrap().to_string();
        if function.name.starts_with("$") {
            function.name = function.name[1..].to_string()
        }

        if !function.name.contains("stdarch_test_shim") {
            continue;
        }

        assert!(ret.insert(function));
    }
    return ret;
}
