import { newPathAssigner } from "../path-utils/path-assigner.js";
/**
 * Extracts inline scripts from flow modules, converting them to separate files
 * and replacing the original content with file references.
 *
 * @param modules - Array of flow modules to process
 * @param mapping - Optional mapping of module IDs to custom file paths
 * @param separator - Path separator to use
 * @param defaultTs - Default TypeScript runtime to use ("bun" or "deno")
 * @param pathAssigner - Optional path assigner to reuse (for nested calls)
 * @returns Array of inline scripts with their paths and content
 */
export function extractInlineScripts(modules, mapping = {}, separator = "/", defaultTs, pathAssigner) {
    // Create pathAssigner only if not provided (top-level call), but reuse it for nested calls
    const assigner = pathAssigner ?? newPathAssigner(defaultTs ?? "bun");
    return modules.flatMap((m) => {
        if (m.value.type == "rawscript") {
            const [basePath, ext] = assigner.assignPath(m.summary, m.value.language);
            const path = mapping[m.id] ?? basePath + ext;
            const content = m.value.content;
            const r = [{ path: path, content: content }];
            m.value.content = "!inline " + path.replaceAll(separator, "/");
            const lock = m.value.lock;
            if (lock && lock != "") {
                const lockPath = basePath + "lock";
                m.value.lock = "!inline " + lockPath.replaceAll(separator, "/");
                r.push({ path: lockPath, content: lock });
            }
            return r;
        }
        else if (m.value.type == "forloopflow") {
            return extractInlineScripts(m.value.modules, mapping, separator, defaultTs, assigner);
        }
        else if (m.value.type == "branchall") {
            return m.value.branches.flatMap((b) => extractInlineScripts(b.modules, mapping, separator, defaultTs, assigner));
        }
        else if (m.value.type == "whileloopflow") {
            return extractInlineScripts(m.value.modules, mapping, separator, defaultTs, assigner);
        }
        else if (m.value.type == "branchone") {
            return [
                ...m.value.branches.flatMap((b) => extractInlineScripts(b.modules, mapping, separator, defaultTs, assigner)),
                ...extractInlineScripts(m.value.default, mapping, separator, defaultTs, assigner),
            ];
        }
        else {
            return [];
        }
    });
}
/**
 * Extracts the current mapping of module IDs to file paths from flow modules
 * by analyzing existing inline script references.
 *
 * @param modules - Array of flow modules to analyze (can be undefined)
 * @param mapping - Existing mapping to extend (defaults to empty object)
 * @returns Record mapping module IDs to their corresponding file paths
 */
export function extractCurrentMapping(modules, mapping = {}) {
    if (!modules || !Array.isArray(modules)) {
        return mapping;
    }
    modules.forEach((m) => {
        if (!m?.value?.type) {
            return;
        }
        if (m.value.type === "rawscript") {
            if (m.value.content && m.value.content.startsWith("!inline ")) {
                mapping[m.id] = m.value.content.trim().split(" ")[1];
            }
        }
        else if (m.value.type === "forloopflow" ||
            m.value.type === "whileloopflow") {
            extractCurrentMapping(m.value.modules, mapping);
        }
        else if (m.value.type === "branchall") {
            m.value.branches.forEach((b) => extractCurrentMapping(b.modules, mapping));
        }
        else if (m.value.type === "branchone") {
            m.value.branches.forEach((b) => extractCurrentMapping(b.modules, mapping));
            extractCurrentMapping(m.value.default, mapping);
        }
    });
    return mapping;
}
