import path from 'node:path';
import { ensureDir, nowIso, PACKAGE_VERSION, readJson, writeJsonAtomic } from '../fsx.js';
export const GIT_POLICY_SCHEMA = 'sks.git-policy.v1';
export const SHARED_MEMORY_MANIFEST_SCHEMA = 'sks.shared-memory-manifest.v1';
export const GIT_HYGIENE_BLOCK = 'SKS MANAGED GIT HYGIENE';
export const GIT_ATTRIBUTES_BLOCK = 'SKS MANAGED GIT ATTRIBUTES';
export const SHARED_MEMORY_TRACK = [
    '.sneakoscope/wiki/records/**/*.json',
    '.sneakoscope/wiki/wrongness/**/*.json',
    '.sneakoscope/wiki/image-voxels/**/*.json',
    '.sneakoscope/wiki/avoidance-rules/**/*.json',
    '.sneakoscope/wiki/summaries/**/*.md',
    '.sneakoscope/wiki/project-policy.json',
    '.sneakoscope/shared-memory-manifest.json',
    '.sneakoscope/git-policy.json'
];
export const GENERATED_INDEX_IGNORE = [
    '.sneakoscope/wiki/indexes/**/*.json',
    '.sneakoscope/wiki/context-packs/**/*.json',
    '.sneakoscope/wiki/tmp/**'
];
export const LOCAL_RUNTIME_IGNORE = [
    '.sneakoscope/missions/**',
    '.sneakoscope/reports/**',
    '.sneakoscope/tmp/**',
    '.sneakoscope/cache/**',
    '.sneakoscope/arenas/**',
    '.sneakoscope/processes/**',
    '.sneakoscope/bench/**',
    '.sneakoscope/blackbox/**',
    '.sneakoscope/logs/**',
    '.sneakoscope/state/**',
    '.sneakoscope/db/**',
    '.sneakoscope/evidence/**',
    '.sneakoscope/proof/**',
    '.sneakoscope/perf/**',
    '.sneakoscope/research/**',
    '.sneakoscope/skills/**',
    '.sneakoscope/smoke-archives/**',
    '.sneakoscope/memory/**',
    '.sneakoscope/manifest.json',
    '.sneakoscope/policy.json',
    '.sneakoscope/db-safety.json',
    '.sneakoscope/db-safety-scan.json',
    '.sneakoscope/harness-guard.json',
    '.sneakoscope/managed-paths.json',
    '.sneakoscope/wiki/context-pack.json',
    '.sneakoscope/wiki/image-assets.json',
    '.sneakoscope/wiki/image-voxel-ledger.json',
    '.sneakoscope/wiki/wrongness-ledger.json',
    '.sneakoscope/wiki/wrongness-index.json',
    '.sneakoscope/wiki/wrongness-summary.md',
    '.sneakoscope/wiki/image-wrongness-index.json',
    '.sneakoscope/wiki/visual-anchors.json',
    '.sneakoscope/wiki/last-sweep-report.json',
    '.sneakoscope/**/*.log'
];
export const SHARED_MEMORY_DIRS = [
    '.sneakoscope/wiki/records/claims',
    '.sneakoscope/wiki/wrongness',
    '.sneakoscope/wiki/image-voxels',
    '.sneakoscope/wiki/avoidance-rules',
    '.sneakoscope/wiki/summaries',
    '.sneakoscope/wiki/indexes',
    '.sneakoscope/wiki/context-packs',
    '.sneakoscope/wiki/tmp'
];
export const LOCAL_RUNTIME_DIRS = [
    '.sneakoscope/missions',
    '.sneakoscope/reports',
    '.sneakoscope/tmp',
    '.sneakoscope/cache',
    '.sneakoscope/arenas',
    '.sneakoscope/processes',
    '.sneakoscope/bench',
    '.sneakoscope/blackbox',
    '.sneakoscope/logs',
    '.sneakoscope/state',
    '.sneakoscope/db',
    '.sneakoscope/evidence',
    '.sneakoscope/proof',
    '.sneakoscope/perf',
    '.sneakoscope/research',
    '.sneakoscope/skills',
    '.sneakoscope/smoke-archives',
    '.sneakoscope/memory'
];
export function normalizeGitPolicyMode(value = 'team') {
    const mode = String(value || 'team').trim().toLowerCase();
    if (mode === 'solo' || mode === 'team' || mode === 'strict-team' || mode === 'ci')
        return mode;
    throw new Error(`Invalid SKS git policy mode: ${value}`);
}
export function gitPolicyPath(root) {
    return path.join(root, '.sneakoscope', 'git-policy.json');
}
export function sharedMemoryManifestPath(root) {
    return path.join(root, '.sneakoscope', 'shared-memory-manifest.json');
}
export function defaultGitPolicy(mode = 'team') {
    return {
        schema: GIT_POLICY_SCHEMA,
        version: PACKAGE_VERSION,
        mode,
        shared_memory: {
            track: [...SHARED_MEMORY_TRACK],
            generated_ignore: [...GENERATED_INDEX_IGNORE]
        },
        local_runtime: {
            ignore: [...LOCAL_RUNTIME_IGNORE]
        },
        large_artifacts: {
            image_binary_policy: 'lfs_or_manual',
            track_raw_screenshots: false,
            max_tracked_file_bytes: 262144
        },
        security: {
            require_redaction: true,
            block_secret_patterns: true,
            block_mock_real_confusion: true
        }
    };
}
export function defaultSharedMemoryManifest(policy = defaultGitPolicy()) {
    return {
        schema: SHARED_MEMORY_MANIFEST_SCHEMA,
        version: policy.version,
        generated_at: nowIso(),
        mode: policy.mode,
        source_of_truth: 'canonical_sharded_records',
        shared_memory_plane: [
            row('claims', '.sneakoscope/wiki/records/claims/<claim-id>.json', 'sks.triwiki-claim-record.v1'),
            row('wrongness', '.sneakoscope/wiki/wrongness/<wrongness-id>.json', 'sks.triwiki-wrongness-record.v1'),
            row('image_voxels', '.sneakoscope/wiki/image-voxels/<image-asset-id>/<anchor-id>.json', 'sks.image-voxel-record.v1'),
            row('avoidance_rules', '.sneakoscope/wiki/avoidance-rules/<rule-id>.json', 'sks.avoidance-rule-record.v1'),
            row('summaries', '.sneakoscope/wiki/summaries/*.md', 'markdown-summary')
        ],
        generated_indexes: [
            generated('project_index', '.sneakoscope/wiki/indexes/project-index.json', 'sks wiki rebuild-index --json'),
            generated('wrongness_index', '.sneakoscope/wiki/indexes/wrongness-index.json', 'sks wiki rebuild-index --json'),
            generated('context_packs', '.sneakoscope/wiki/context-packs/latest.json', 'sks wiki refresh')
        ],
        local_runtime_plane: LOCAL_RUNTIME_DIRS.map((dir) => ({
            id: dir.split('/').at(-1) || dir,
            path: `${dir}/**`,
            git: 'ignored'
        })),
        promotion_flow: [
            'mission runtime artifact',
            'validate schema',
            'secret scan',
            'mock/static policy check',
            'redact when requested',
            'write deterministic canonical shard',
            'rebuild ignored indexes',
            'show intended git status'
        ],
        security: policy.security
    };
}
export async function ensureGitPolicy(root, opts = {}) {
    const mode = normalizeGitPolicyMode(opts.mode || 'team');
    const current = await readJson(gitPolicyPath(root), null);
    const policy = normalizeGitPolicy({
        ...(current?.schema === GIT_POLICY_SCHEMA ? current : defaultGitPolicy(mode)),
        version: PACKAGE_VERSION,
        mode
    });
    if (opts.imageBinaryPolicy) {
        const imagePolicy = String(opts.imageBinaryPolicy);
        if (!['off', 'lfs', 'manual', 'lfs_or_manual'].includes(imagePolicy))
            throw new Error(`Invalid image binary policy: ${imagePolicy}`);
        policy.large_artifacts.image_binary_policy = imagePolicy;
    }
    if (opts.write) {
        await ensureSharedMemoryDirs(root);
        await writeJsonAtomic(gitPolicyPath(root), policy);
        await writeJsonAtomic(sharedMemoryManifestPath(root), defaultSharedMemoryManifest(policy));
    }
    return policy;
}
export async function readGitPolicy(root) {
    const current = await readJson(gitPolicyPath(root), null);
    return normalizeGitPolicy(current?.schema === GIT_POLICY_SCHEMA ? current : defaultGitPolicy());
}
export async function ensureSharedMemoryDirs(root) {
    for (const dir of [...SHARED_MEMORY_DIRS, ...LOCAL_RUNTIME_DIRS])
        await ensureDir(path.join(root, dir));
}
export function classifySksPath(relPath, policy = defaultGitPolicy()) {
    const rel = normalizeRelPath(relPath);
    if (!rel.startsWith('.sneakoscope/'))
        return 'not_sks';
    if (isLocalRuntimePath(rel, policy))
        return 'local_runtime';
    if (isGeneratedIndexPath(rel, policy))
        return 'generated_index';
    if (isSharedMemoryPath(rel, policy))
        return 'shared_memory';
    return 'unknown_sks';
}
export function isSharedMemoryPath(relPath, _policy = defaultGitPolicy()) {
    const rel = normalizeRelPath(relPath);
    return rel.startsWith('.sneakoscope/wiki/records/')
        || rel.startsWith('.sneakoscope/wiki/wrongness/')
        || rel.startsWith('.sneakoscope/wiki/image-voxels/')
        || rel.startsWith('.sneakoscope/wiki/avoidance-rules/')
        || rel.startsWith('.sneakoscope/wiki/summaries/')
        || rel === '.sneakoscope/wiki/project-policy.json'
        || rel === '.sneakoscope/git-policy.json'
        || rel === '.sneakoscope/shared-memory-manifest.json';
}
export function isGeneratedIndexPath(relPath, _policy = defaultGitPolicy()) {
    const rel = normalizeRelPath(relPath);
    return rel.startsWith('.sneakoscope/wiki/indexes/')
        || rel.startsWith('.sneakoscope/wiki/context-packs/')
        || rel.startsWith('.sneakoscope/wiki/tmp/');
}
export function isLocalRuntimePath(relPath, _policy = defaultGitPolicy()) {
    const rel = normalizeRelPath(relPath);
    return LOCAL_RUNTIME_DIRS.some((dir) => rel === dir || rel.startsWith(`${dir}/`))
        || LOCAL_RUNTIME_IGNORE.filter((pattern) => !pattern.includes('*')).some((file) => rel === file)
        || /^\.sneakoscope\/.+\.log$/.test(rel);
}
export function normalizeRelPath(value) {
    return String(value || '').replaceAll('\\', '/').replace(/^\.\//, '');
}
export function normalizeGitPolicy(value) {
    const base = defaultGitPolicy(normalizeGitPolicyMode(value?.mode || 'team'));
    return {
        ...base,
        ...value,
        schema: GIT_POLICY_SCHEMA,
        version: PACKAGE_VERSION,
        mode: normalizeGitPolicyMode(value?.mode || base.mode),
        shared_memory: {
            track: arrayOr(value?.shared_memory?.track, base.shared_memory.track),
            generated_ignore: arrayOr(value?.shared_memory?.generated_ignore, base.shared_memory.generated_ignore)
        },
        local_runtime: {
            ignore: arrayOr(value?.local_runtime?.ignore, base.local_runtime.ignore)
        },
        large_artifacts: {
            ...base.large_artifacts,
            ...(value?.large_artifacts || {})
        },
        security: {
            ...base.security,
            ...(value?.security || {})
        }
    };
}
function row(id, recordPath, recordSchema) {
    return {
        id,
        path: recordPath,
        record_schema: recordSchema,
        git: 'tracked',
        merge: 'single-record-json'
    };
}
function generated(id, generatedPath, rebuild) {
    return {
        id,
        path: generatedPath,
        git: 'ignored',
        rebuild
    };
}
function arrayOr(value, fallback) {
    return Array.isArray(value) && value.every((item) => typeof item === 'string') ? [...value] : [...fallback];
}
//# sourceMappingURL=git-policy.js.map