/**
 * Will transform all source file to get all relative functions
 */
import ignore from "ignore";
import { main } from "assemblyscript/asc";
import { join, relative, resolve } from "node:path";
import { getIncludeFiles } from "../utils/pathResolver.js";
import { projectRoot } from "../utils/projectRoot.js";
const sourceFunctions = new Map();
export async function precompile(includes, excludes, testcases, flags, transformFunction = join(projectRoot, "transform", "listFunctions.mjs")) {
    // if specify testcases, use testcases for unittest
    // otherwise, get testcases(*.test.ts) in includes directory
    const testCodePaths = testcases ?? getRelatedFiles(includes, excludes, (path) => path.endsWith(".test.ts"));
    const sourceCodePaths = getRelatedFiles(includes, excludes, (path) => !path.endsWith(".test.ts"));
    const sourceCodeTransforms = [];
    for (const sourceCodePath of sourceCodePaths.values()) {
        sourceCodeTransforms.push(transform(sourceCodePath, transformFunction, flags));
    }
    await Promise.all(sourceCodeTransforms);
    return {
        testCodePaths,
        sourceFunctions,
    };
}
// a. include in config
// b. exclude in config
export function getRelatedFiles(includes, excludes, filter) {
    const result = [];
    const includeFiles = getIncludeFiles(includes, (path) => path.endsWith(".ts")); // a
    const exc = ignore().add(excludes);
    for (const path of includeFiles) {
        const relativePath = relative(".", path);
        if (relativePath.startsWith("..")) {
            throw new Error(`file ${path} out of scope (${resolve(".")})`);
        }
        if (exc.ignores(relativePath)) {
            continue; // ab
        }
        if (filter(path)) {
            result.push(path.replaceAll(/\\/g, "/"));
        }
    }
    return result;
}
async function transform(sourceCodePath, transformFunction, flags) {
    let ascArgv = [sourceCodePath, "--noEmit", "--disableWarning", "--transform", transformFunction, "-O0"];
    if (flags) {
        const argv = flags.split(" ");
        ascArgv = ascArgv.concat(argv);
    }
    const { error, stderr } = await main(ascArgv);
    if (error) {
        // eslint-disable-next-line @typescript-eslint/no-base-to-string
        console.error(stderr.toString());
        throw error;
    }
    sourceFunctions.set(sourceCodePath, functionInfos);
}
//# sourceMappingURL=precompile.js.map