import crypto from 'node:crypto';
import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { readJsonFile, writeJsonFile } from './fs-json.js';
const VAULT_PATH = path.join(os.homedir(), '.mcporter', 'credentials.json');
async function readVault() {
    let shouldRewrite = false;
    try {
        const existing = await readJsonFile(VAULT_PATH);
        if (existing && existing.version === 1 && existing.entries && typeof existing.entries === 'object') {
            return existing;
        }
        // Unexpected shape; rewrite.
        shouldRewrite = true;
    }
    catch {
        // Corrupt or unreadable vault; reset to empty.
        shouldRewrite = true;
    }
    const empty = { version: 1, entries: {} };
    if (shouldRewrite) {
        await writeVault(empty);
    }
    return empty;
}
async function writeVault(contents) {
    const dir = path.dirname(VAULT_PATH);
    await fs.mkdir(dir, { recursive: true });
    await writeJsonFile(VAULT_PATH, contents);
}
export function vaultKeyForDefinition(definition) {
    const descriptor = {
        name: definition.name,
        url: definition.command.kind === 'http' ? definition.command.url.toString() : null,
        command: definition.command.kind === 'stdio'
            ? { command: definition.command.command, args: definition.command.args ?? [] }
            : null,
    };
    const hash = crypto.createHash('sha256').update(JSON.stringify(descriptor)).digest('hex').slice(0, 16);
    return `${definition.name}|${hash}`;
}
export async function loadVaultEntry(definition) {
    const vault = await readVault();
    return vault.entries[vaultKeyForDefinition(definition)];
}
export async function saveVaultEntry(definition, patch) {
    const vault = await readVault();
    const key = vaultKeyForDefinition(definition);
    const current = vault.entries[key] ?? {
        serverName: definition.name,
        serverUrl: definition.command.kind === 'http' ? definition.command.url.toString() : undefined,
        updatedAt: new Date().toISOString(),
    };
    vault.entries[key] = {
        ...current,
        ...patch,
        updatedAt: new Date().toISOString(),
    };
    await writeVault(vault);
}
export async function clearVaultEntry(definition, scope) {
    const vault = await readVault();
    const key = vaultKeyForDefinition(definition);
    const existing = vault.entries[key];
    if (!existing) {
        return;
    }
    if (scope === 'all') {
        delete vault.entries[key];
    }
    else {
        const updated = { ...existing };
        if (scope === 'tokens') {
            delete updated.tokens;
        }
        if (scope === 'client') {
            delete updated.clientInfo;
        }
        if (scope === 'verifier') {
            delete updated.codeVerifier;
        }
        if (scope === 'state') {
            delete updated.state;
        }
        updated.updatedAt = new Date().toISOString();
        vault.entries[key] = updated;
    }
    await writeVault(vault);
}
//# sourceMappingURL=oauth-vault.js.map