/**
 * Config support for Hippo: reads .hippo/config.json with sane defaults.
 */
import * as fs from 'fs';
import * as path from 'path';
import { DEFAULT_PHYSICS_CONFIG, mergePhysicsConfig } from './physics-config.js';
const DEFAULT_CONFIG = {
    defaultHalfLifeDays: 7,
    defaultBudget: 4000,
    defaultContextBudget: 3000,
    decayBasis: 'adaptive',
    autoLearnOnSleep: true,
    autoShareOnSleep: true,
    autoSleep: {
        enabled: true,
        threshold: 50,
    },
    embeddings: {
        enabled: 'auto',
        model: 'Xenova/all-MiniLM-L6-v2',
        hybridWeight: 0.6,
    },
    global: {
        enabled: true,
    },
    gitLearnPatterns: [
        'fix', 'revert', 'bug', 'error', 'hotfix', 'bugfix',
        'refactor', 'perf', 'chore', 'breaking', 'deprecate',
    ],
    physics: { ...DEFAULT_PHYSICS_CONFIG },
    mmr: {
        enabled: true,
        lambda: 0.7,
    },
    search: {
        localBump: 1.2,
    },
    replay: {
        count: 5,
    },
    autoTraceCapture: true,
    autoTraceWindowDays: 7,
    pinnedInject: {
        enabled: true,
        budget: 1500,
    },
    extraction: {
        enabled: 'auto',
        model: 'claude-sonnet-4-6',
    },
    multihop: {
        enabled: false,
    },
    salience: {
        enabled: false,
        recentWindow: 20,
        overlapThreshold: 0.6,
        minContentLength: 5,
        maxRepeatErrors: 4,
    },
    ambient: {
        enabled: true,
    },
};
export function loadConfig(hippoRoot) {
    const configPath = path.join(hippoRoot, 'config.json');
    if (!fs.existsSync(configPath))
        return { ...DEFAULT_CONFIG };
    try {
        const raw = JSON.parse(fs.readFileSync(configPath, 'utf8'));
        const basis = raw.decayBasis;
        const validBasis = basis === 'clock' || basis === 'session' || basis === 'adaptive';
        return {
            defaultHalfLifeDays: raw.defaultHalfLifeDays ?? DEFAULT_CONFIG.defaultHalfLifeDays,
            defaultBudget: raw.defaultBudget ?? DEFAULT_CONFIG.defaultBudget,
            defaultContextBudget: raw.defaultContextBudget ?? DEFAULT_CONFIG.defaultContextBudget,
            decayBasis: validBasis ? basis : DEFAULT_CONFIG.decayBasis,
            autoLearnOnSleep: raw.autoLearnOnSleep ?? DEFAULT_CONFIG.autoLearnOnSleep,
            autoShareOnSleep: raw.autoShareOnSleep ?? DEFAULT_CONFIG.autoShareOnSleep,
            autoSleep: { ...DEFAULT_CONFIG.autoSleep, ...(raw.autoSleep ?? {}) },
            embeddings: { ...DEFAULT_CONFIG.embeddings, ...(raw.embeddings ?? {}) },
            global: { ...DEFAULT_CONFIG.global, ...(raw.global ?? {}) },
            gitLearnPatterns: raw.gitLearnPatterns ?? DEFAULT_CONFIG.gitLearnPatterns,
            physics: mergePhysicsConfig(raw.physics),
            mmr: { ...DEFAULT_CONFIG.mmr, ...(raw.mmr ?? {}) },
            search: { ...DEFAULT_CONFIG.search, ...(raw.search ?? {}) },
            replay: { ...DEFAULT_CONFIG.replay, ...(raw.replay ?? {}) },
            autoTraceCapture: raw.autoTraceCapture ?? DEFAULT_CONFIG.autoTraceCapture,
            autoTraceWindowDays: raw.autoTraceWindowDays ?? DEFAULT_CONFIG.autoTraceWindowDays,
            pinnedInject: { ...DEFAULT_CONFIG.pinnedInject, ...(raw.pinnedInject ?? {}) },
            extraction: { ...DEFAULT_CONFIG.extraction, ...(raw.extraction ?? {}) },
            multihop: { ...DEFAULT_CONFIG.multihop, ...(raw.multihop ?? {}) },
            salience: { ...DEFAULT_CONFIG.salience, ...(raw.salience ?? {}) },
            ambient: { ...DEFAULT_CONFIG.ambient, ...(raw.ambient ?? {}) },
        };
    }
    catch (err) {
        if (fs.existsSync(configPath)) {
            console.error(`Warning: failed to parse ${configPath}: ${err instanceof Error ? err.message : err}`);
        }
        return { ...DEFAULT_CONFIG };
    }
}
export function saveConfig(hippoRoot, config) {
    const configPath = path.join(hippoRoot, 'config.json');
    fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');
}
//# sourceMappingURL=config.js.map