import { loadSourcesConfig } from '../config/sources.js';
import { readJsonFile, writeJsonFile } from '../lib/json.js';
import { logger } from '../lib/logger.js';
import { getStatePath } from '../lib/paths.js';
import { SkillSchema } from '../models/records.js';
const OUTPUT_PATH = getStatePath('data/curated/skills.json');
export async function ingestSkills() {
    const { skills } = await loadSourcesConfig();
    const records = await loadSkillRecords(skills);
    const merged = mergeSkillRecords(records);
    await writeJsonFile(OUTPUT_PATH, merged);
    logger.info(`Wrote ${merged.length} skills to ${OUTPUT_PATH}`);
    return merged;
}
async function loadSkillRecords(descriptors) {
    const perSource = await Promise.all(descriptors.map(async (descriptor) => {
        const payload = await readJsonFile(descriptor.file);
        return payload.map((record) => ({
            source: descriptor,
            record: SkillSchema.parse(record)
        }));
    }));
    return perSource.flat();
}
function mergeSkillRecords(records) {
    const state = new Map();
    for (const entry of records) {
        const existing = state.get(entry.record.id);
        if (!existing) {
            state.set(entry.record.id, { priority: entry.source.priority, record: entry.record });
            continue;
        }
        const preferIncoming = shouldPreferIncoming(entry, existing);
        if (preferIncoming) {
            state.set(entry.record.id, {
                priority: entry.source.priority,
                record: mergeSkill(entry.record, existing.record)
            });
        }
        else {
            state.set(entry.record.id, {
                priority: existing.priority,
                record: mergeSkill(existing.record, entry.record)
            });
        }
    }
    return Array.from(state.values())
        .map((entry) => entry.record)
        .sort((a, b) => a.id.localeCompare(b.id));
}
function shouldPreferIncoming(entry, existing) {
    if (entry.source.priority !== existing.priority) {
        return entry.source.priority > existing.priority;
    }
    return entry.record.lastValidated >= existing.record.lastValidated;
}
function mergeSkill(primary, secondary) {
    const mergedProficiencyLevels = dedupeStrings([
        ...primary.proficiencyLevels,
        ...secondary.proficiencyLevels
    ]);
    return {
        ...primary,
        description: secondary.description.length > primary.description.length ? secondary.description : primary.description,
        aliases: dedupeStrings([...primary.aliases, ...secondary.aliases]),
        proficiencyLevels: mergedProficiencyLevels.length > 0
            ? mergedProficiencyLevels
            : primary.proficiencyLevels,
        taxonomyPath: primary.taxonomyPath.length ? primary.taxonomyPath : secondary.taxonomyPath,
        lastValidated: primary.lastValidated >= secondary.lastValidated ? primary.lastValidated : secondary.lastValidated
    };
}
function dedupeStrings(values) {
    return Array.from(new Set(values)).sort((a, b) => a.localeCompare(b));
}
export { mergeSkillRecords, mergeSkill, dedupeStrings };
