"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.VIRTUAL_WORKSPACE_COMPONENT_ID = void 0;
exports.normalizeArchitectureWorkspaceModel = normalizeArchitectureWorkspaceModel;
exports.loadNormalizedArchitectureWorkspaceModel = loadNormalizedArchitectureWorkspaceModel;
const architectureInit_1 = require("./architectureInit");
exports.VIRTUAL_WORKSPACE_COMPONENT_ID = 'workspace';
function normalizeRepoDefaults(contract) {
    return {
        version: contract.version,
        projectName: contract.projectName,
        repoTopology: contract.repoTopology,
        projectKinds: [...contract.projectKinds],
        stacks: { ...contract.stacks },
        architectureStyle: contract.architectureStyle,
        database: contract.database,
        tenantModel: contract.tenantModel,
        rbac: contract.rbac,
        apiStyle: contract.apiStyle,
        authStyle: contract.authStyle,
        implementationProfile: contract.implementationProfile,
        createdAtUtc: contract.createdAtUtc,
        structure: { ...contract.structure },
        artifacts: { ...contract.artifacts },
        layers: { ...contract.layers },
        governance: {
            ...contract.governance,
            validation: { ...(contract.governance.validation ?? {}) },
        },
    };
}
function normalizeComponent(id, source, defaults, component) {
    return {
        id,
        name: component?.name ?? defaults.projectName,
        source,
        ...(component?.path ? { path: component.path } : {}),
        ...(component?.type ? { type: component.type } : {}),
        ...(component?.stack ? { stack: component.stack } : {}),
        ...(component?.kind ? { kind: component.kind } : {}),
        repoTopology: component?.repoTopology ?? defaults.repoTopology,
        projectKinds: [...(component?.projectKinds ?? defaults.projectKinds)],
        stacks: { ...(component?.stacks ?? defaults.stacks) },
        architectureStyle: component?.architectureStyle ?? defaults.architectureStyle,
        database: component?.database ?? defaults.database,
        tenantModel: component?.tenantModel ?? defaults.tenantModel,
        rbac: component?.rbac ?? defaults.rbac,
        apiStyle: component?.apiStyle ?? defaults.apiStyle,
        authStyle: component?.authStyle ?? defaults.authStyle,
        implementationProfile: component?.implementationProfile ?? defaults.implementationProfile,
        structure: {
            ...defaults.structure,
            ...(component?.structure ?? {}),
        },
        artifacts: {
            ...defaults.artifacts,
            ...(component?.artifacts ?? {}),
        },
        modules: component?.modules ?? {},
        ...(component?.allowedDependencies
            ? { allowedDependencies: [...component.allowedDependencies] }
            : {}),
        layers: {
            ...defaults.layers,
            ...(component?.layers ?? {}),
        },
        governance: {
            ...defaults.governance,
            ...(component?.governance ?? {}),
            validation: {
                ...(defaults.governance.validation ?? {}),
                ...(component?.governance?.validation ?? {}),
            },
        },
    };
}
function hasDeclaredComponents(components) {
    return !!components && Object.keys(components).length > 0;
}
function getDeclaredComponentEntries(components) {
    const entries = Array.isArray(components)
        ? components
            .map((component, index) => [
            component?.id ?? `component-${index + 1}`,
            component,
        ])
            .filter((entry) => Boolean(entry[1]))
        : Object.entries(components)
            .filter((entry) => Boolean(entry[1]))
            .sort(([left], [right]) => left.localeCompare(right));
    const seenPaths = new Set();
    return entries.filter(([, component]) => {
        const normalizedPath = normalizeArchitectureWorkspacePath(component.path);
        if (!normalizedPath) {
            return true;
        }
        if (seenPaths.has(normalizedPath)) {
            return false;
        }
        seenPaths.add(normalizedPath);
        return true;
    });
}
function normalizeArchitectureWorkspacePath(value) {
    const normalized = value
        ?.replace(/\\/g, '/')
        .replace(/^\.\//u, '')
        .replace(/\/+$/u, '')
        .trim();
    return normalized && normalized.length > 0 ? normalized : undefined;
}
function normalizeResource(id, resource) {
    return {
        id,
        name: resource.name ?? id,
        ...(resource.type ? { type: resource.type } : {}),
        ...(resource.provider ? { provider: resource.provider } : {}),
        ...(resource.path ? { path: resource.path } : {}),
        ...(resource.ownerComponent ? { ownerComponent: resource.ownerComponent } : {}),
        ...(resource.component ? { component: resource.component } : {}),
        components: [...(resource.components ?? [])],
        dependsOn: [...(resource.dependsOn ?? [])],
        metadata: { ...(resource.metadata ?? {}) },
    };
}
function normalizeResources(resources) {
    if (!resources || Object.keys(resources).length === 0) {
        return undefined;
    }
    const entries = Array.isArray(resources)
        ? resources
            .map((resource, index) => [
            resource?.id ?? `resource-${index + 1}`,
            resource,
        ])
            .filter((entry) => Boolean(entry[1]))
        : Object.entries(resources)
            .filter((entry) => Boolean(entry[1]))
            .sort(([left], [right]) => left.localeCompare(right));
    return entries
        .map(([resourceId, resource]) => normalizeResource(resourceId, resource));
}
function normalizeArchitectureWorkspaceModel(contract) {
    const repoDefaults = normalizeRepoDefaults(contract);
    const components = hasDeclaredComponents(contract.components)
        ? getDeclaredComponentEntries(contract.components).map(([componentId, component]) => normalizeComponent(componentId, 'declared', repoDefaults, component))
        : [
            normalizeComponent(exports.VIRTUAL_WORKSPACE_COMPONENT_ID, 'virtual', repoDefaults, {
                name: contract.projectName,
                modules: contract.modules,
            }),
        ];
    const resources = normalizeResources(contract.resources);
    return {
        version: contract.version,
        projectName: contract.projectName,
        repoDefaults,
        components,
        ...(resources ? { resources } : {}),
    };
}
async function loadNormalizedArchitectureWorkspaceModel(workspaceRoot) {
    const contract = await (0, architectureInit_1.loadArchitectureContract)(workspaceRoot);
    return contract ? normalizeArchitectureWorkspaceModel(contract) : undefined;
}
//# sourceMappingURL=architectureWorkspaceModel.js.map