import * as fs from "node:fs";
import * as path from "node:path";
import { ok } from "../types/result.js";
import { resolveSourcePackageImport, resolveSourcePackageImportFromPackageRoot, } from "../resolver/source-package-resolution.js";
const findAuthoritativePackageRootForImport = (importSpecifier, authoritativeTsonicPackageRoots) => {
    if (!authoritativeTsonicPackageRoots) {
        return undefined;
    }
    let bestMatch;
    for (const [packageName, packageRoot] of authoritativeTsonicPackageRoots) {
        if (importSpecifier === packageName ||
            importSpecifier.startsWith(`${packageName}/`)) {
            if (!bestMatch || packageName.length > bestMatch.length) {
                bestMatch = packageName;
            }
            if (packageName === importSpecifier) {
                return packageRoot;
            }
        }
    }
    return bestMatch ? authoritativeTsonicPackageRoots.get(bestMatch) : undefined;
};
export const resolveSourceBindingFiles = (bindings, kinds, containingFile, projectRoot, surface, authoritativeTsonicPackageRoots) => {
    const kindSet = new Set(kinds);
    const seenImports = new Set();
    const resolvedPaths = [];
    for (const [, descriptor] of bindings.getAllBindings()) {
        if (!kindSet.has(descriptor.kind)) {
            continue;
        }
        const sourceImport = descriptor.sourceImport;
        if (typeof sourceImport !== "string" ||
            sourceImport.length === 0 ||
            seenImports.has(sourceImport)) {
            continue;
        }
        seenImports.add(sourceImport);
        const authoritativePackageRoot = findAuthoritativePackageRootForImport(sourceImport, authoritativeTsonicPackageRoots);
        const resolved = authoritativePackageRoot !== undefined
            ? resolveSourcePackageImportFromPackageRoot(sourceImport, authoritativePackageRoot, surface, projectRoot)
            : resolveSourcePackageImport(sourceImport, containingFile, surface, projectRoot);
        if (!resolved.ok) {
            return resolved;
        }
        if (resolved.value) {
            resolvedPaths.push(resolved.value.resolvedPath);
        }
    }
    return ok(resolvedPaths);
};
const collectSourceOwnedTypeFiles = (bindings) => {
    const seenPaths = new Set();
    const resolvedPaths = [];
    for (const type of bindings.getTypesMap().values()) {
        for (const member of type.members) {
            const sourceFilePath = member.sourceOrigin?.filePath;
            if (!sourceFilePath) {
                continue;
            }
            const resolvedPath = path.resolve(sourceFilePath);
            if (seenPaths.has(resolvedPath) || !fs.existsSync(resolvedPath)) {
                continue;
            }
            seenPaths.add(resolvedPath);
            resolvedPaths.push(resolvedPath);
        }
    }
    return resolvedPaths;
};
export const resolveSourceBackedBindingFiles = (bindings, containingFile, projectRoot, surface, authoritativeTsonicPackageRoots) => {
    const resolvedSimpleBindings = resolveSourceBindingFiles(bindings, ["global", "module"], containingFile, projectRoot, surface, authoritativeTsonicPackageRoots);
    if (!resolvedSimpleBindings.ok) {
        return resolvedSimpleBindings;
    }
    return ok(Array.from(new Set([
        ...resolvedSimpleBindings.value,
        ...collectSourceOwnedTypeFiles(bindings),
    ])));
};
//# sourceMappingURL=source-binding-imports.js.map