"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.detectSmartInit = detectSmartInit;
exports.detectSmartInitWithDetectorCallCounts = detectSmartInitWithDetectorCallCounts;
const repoTopologyDetection_1 = require("./repoTopologyDetection");
const moduleDetection_1 = require("./moduleDetection");
const toolingHintDetection_1 = require("./toolingHintDetection");
const architectureStyleDetection_1 = require("./architectureStyleDetection");
const componentDetection_1 = require("./componentDetection");
const archpilotIgnore_1 = require("./archpilotIgnore");
const architectureProposalBuilder_1 = require("./architectureProposalBuilder");
const runContext_1 = require("./runContext");
function uniqueInOrder(values) {
    const seen = new Set();
    const result = [];
    for (const value of values) {
        if (seen.has(value)) {
            continue;
        }
        seen.add(value);
        result.push(value);
    }
    return result;
}
function applyMonorepoComponentStackAttribution(stacks, componentDetection, topology) {
    if (topology.topology !== 'monorepo') {
        return stacks;
    }
    const backendStacks = uniqueInOrder(componentDetection.detectedComponents
        .filter((component) => component.kind === 'backend' || component.kind === 'worker')
        .map((component) => component.stack)
        .filter((stack) => Boolean(stack)));
    const frontendStacks = uniqueInOrder(componentDetection.detectedComponents
        .filter((component) => component.kind === 'frontend')
        .map((component) => component.stack)
        .filter((stack) => Boolean(stack)));
    const componentStacks = uniqueInOrder(componentDetection.detectedComponents
        .map((component) => component.stack)
        .filter((stack) => Boolean(stack)));
    return {
        ...stacks,
        stacks: componentStacks.length > 0 ? componentStacks : stacks.stacks,
        backendStacks,
        frontendStacks,
    };
}
function detectSmartInit(workspaceRoot, options) {
    const runContext = options?.runContext ?? (0, runContext_1.createSmartInitRunContext)();
    (0, archpilotIgnore_1.ensureArchpilotIgnoreFileSync)(workspaceRoot);
    const ignoreMatcher = (0, archpilotIgnore_1.loadArchpilotIgnoreMatcher)(workspaceRoot);
    const topology = (0, repoTopologyDetection_1.detectRepoTopology)(workspaceRoot, { ignoreMatcher });
    const rawStacks = runContext.detectStacks(workspaceRoot, { ignoreMatcher });
    const projectKinds = runContext.detectProjectKinds(workspaceRoot, { ignoreMatcher });
    const architectureStyleSignals = (0, architectureStyleDetection_1.detectArchitectureStyleSignals)(workspaceRoot, topology, {
        ignoreMatcher,
    });
    const modules = (0, moduleDetection_1.detectModules)(workspaceRoot, {
        projectKinds: projectKinds.kinds.filter((kind) => kind === 'backend' || kind === 'frontend' || kind === 'library'),
        stacks: rawStacks.stacks,
        ignoreMatcher,
        projectRoots: topology.detectedRoots,
    });
    const componentDetection = (0, componentDetection_1.detectComponents)({
        workspaceRoot,
        topology,
        modules,
        architectureStyleSignals,
        ignoreMatcher,
        runContext,
    });
    const stacks = applyMonorepoComponentStackAttribution(rawStacks, componentDetection, topology);
    const detection = {
        topology,
        stacks,
        projectKinds,
        modules,
        apiDbHints: runContext.detectApiDbHints(workspaceRoot, { ignoreMatcher }),
        toolingHints: (0, toolingHintDetection_1.detectToolingHints)(workspaceRoot, { ignoreMatcher }),
        architectureStyleSignals,
        componentDetection,
        detectedComponents: componentDetection.detectedComponents,
    };
    detection.proposal = (0, architectureProposalBuilder_1.buildArchitectureProposal)(detection);
    return detection;
}
function detectSmartInitWithDetectorCallCounts(workspaceRoot) {
    const runContext = (0, runContext_1.createSmartInitRunContext)();
    const detection = detectSmartInit(workspaceRoot, { runContext });
    return {
        detection,
        detectorCallCounts: runContext.getDetectorCallCounts(),
    };
}
//# sourceMappingURL=smartInitEngine.js.map