"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.OSKeyProvider = void 0;
const child_process_1 = require("child_process");
const key_provider_1 = require("./key-provider");
// ============================================================
// key-provider-os.ts — OS-native key storage provider
//
// Windows: DPAPI via ConvertFrom-Clixml (real encryption, not hex file)
// macOS: security (Keychain CLI)
// Linux: secret-tool (GNOME Keyring / KWallet)
//
// All use CLI wrappers — no native npm modules needed
// ============================================================
class OSKeyProvider {
    name = 'os-native';
    osType = (0, key_provider_1.detectOS)();
    isAvailable() {
        try {
            switch (this.osType) {
                case 'windows': return this.isWindowsAvailable();
                case 'macos': return this.isMacOSAvailable();
                case 'linux': return this.isLinuxAvailable();
                default: return false;
            }
        }
        catch {
            return false;
        }
    }
    healthCheck() {
        const available = this.isAvailable();
        switch (this.osType) {
            case 'windows':
                return { available, os: 'windows', method: 'DPAPI-SecureString', details: available ? 'PowerShell ConvertTo-SecureString/ConvertFrom-SecureString' : 'PowerShell not available' };
            case 'macos':
                return { available, os: 'macos', method: 'Keychain', details: available ? 'security CLI available' : 'security CLI not found' };
            case 'linux':
                return { available, os: 'linux', method: 'SecretService', details: available ? 'secret-tool available' : 'secret-tool not found' };
            default:
                return { available: false, os: 'unknown', method: 'none', details: 'Unsupported OS' };
        }
    }
    // ============================================================
    // Windows — DPAPI via ConvertFrom-SecureString
    // Uses current user's DPAPI scope — keys only readable by same user on same machine
    // ============================================================
    isWindowsAvailable() {
        try {
            (0, child_process_1.execSync)('powershell -Command "ConvertTo-SecureString -String test -AsPlainText -Force"', {
                encoding: 'utf-8', timeout: 5000, stdio: 'pipe',
            });
            return true;
        }
        catch {
            return false;
        }
    }
    windowsGetKey(id) {
        try {
            const safeId = id.replace(/[^a-zA-Z0-9_-]/g, '_');
            // Read the DPAPI-encrypted string from file, then decrypt with current user scope
            const cmd = `powershell -Command "$enc = Get-Content -Path '$env:USERPROFILE\\.fivo\\cell\\keys\\os-${safeId}.dpapi' -ErrorAction Stop; $sec = ConvertTo-SecureString $enc; [System.Runtime.InteropServices.Marshal]::PtrToStringBSTR([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($sec))"`;
            const hex = (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' }).trim();
            if (!hex)
                return null;
            return Buffer.from(hex, 'hex');
        }
        catch {
            return null;
        }
    }
    windowsSetKey(id, key) {
        try {
            const safeId = id.replace(/[^a-zA-Z0-9_-]/g, '_');
            // Convert hex to SecureString (DPAPI-encrypted in current user scope), then save
            const hex = key.toString('hex');
            const cmd = `powershell -Command "New-Item -Path '$env:USERPROFILE\\.fivo\\cell\\keys' -ItemType Directory -Force | Out-Null; $sec = ConvertTo-SecureString '${hex}' -AsPlainText -Force; $enc = ConvertFrom-SecureString $sec; Set-Content -Path '$env:USERPROFILE\\.fivo\\cell\\keys\\os-${safeId}.dpapi' -Value $enc -Force"`;
            (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
            // Clean up old hex file if it exists
            try {
                const fs = require('fs');
                const oldPath = require('path').join(require('os').homedir(), '.fivo', 'cell', 'keys', `os-${safeId}.txt`);
                if (fs.existsSync(oldPath))
                    fs.unlinkSync(oldPath);
            }
            catch { /* ignore */ }
            return true;
        }
        catch {
            return false;
        }
    }
    windowsDeleteKey(id) {
        try {
            const safeId = id.replace(/[^a-zA-Z0-9_-]/g, '_');
            const cmd = `powershell -Command "Remove-Item -Path '$env:USERPROFILE\\.fivo\\cell\\keys\\os-${safeId}.dpapi' -Force -ErrorAction SilentlyContinue; Remove-Item -Path '$env:USERPROFILE\\.fivo\\cell\\keys\\os-${safeId}.txt' -Force -ErrorAction SilentlyContinue"`;
            (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
            return true;
        }
        catch {
            return false;
        }
    }
    // ============================================================
    // macOS — Keychain CLI
    // ============================================================
    isMacOSAvailable() {
        try {
            (0, child_process_1.execSync)('which security', { encoding: 'utf-8', timeout: 3000, stdio: 'pipe' });
            return true;
        }
        catch {
            return false;
        }
    }
    macosGetKey(id) {
        try {
            const result = (0, child_process_1.execSync)(`security find-generic-password -a fivocell -s "cell-${id}" -w 2>/dev/null`, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' }).trim();
            if (!result)
                return null;
            return Buffer.from(result, 'hex');
        }
        catch {
            return null;
        }
    }
    macosSetKey(id, key) {
        try {
            try {
                (0, child_process_1.execSync)(`security delete-generic-password -a fivocell -s "cell-${id}" 2>/dev/null`, {
                    encoding: 'utf-8', timeout: 5000, stdio: 'pipe',
                });
            }
            catch { /* ignore */ }
            (0, child_process_1.execSync)(`security add-generic-password -a fivocell -s "cell-${id}" -w "${key.toString('hex')}" -U`, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
            return true;
        }
        catch {
            return false;
        }
    }
    macosDeleteKey(id) {
        try {
            (0, child_process_1.execSync)(`security delete-generic-password -a fivocell -s "cell-${id}" 2>/dev/null`, {
                encoding: 'utf-8', timeout: 5000, stdio: 'pipe',
            });
            return true;
        }
        catch {
            return false;
        }
    }
    // ============================================================
    // Linux — secret-tool (GNOME Keyring)
    // ============================================================
    isLinuxAvailable() {
        try {
            (0, child_process_1.execSync)('which secret-tool', { encoding: 'utf-8', timeout: 3000, stdio: 'pipe' });
            return true;
        }
        catch {
            return false;
        }
    }
    linuxGetKey(id) {
        try {
            const result = (0, child_process_1.execSync)(`secret-tool lookup service fivocell id "${id}"`, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' }).trim();
            if (!result)
                return null;
            return Buffer.from(result, 'hex');
        }
        catch {
            return null;
        }
    }
    linuxSetKey(id, key) {
        try {
            const cmd = `echo -n "${key.toString('hex')}" | secret-tool store --label="Fivo Cell ${id}" service fivocell id "${id}"`;
            (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe', shell: '/bin/bash' });
            return true;
        }
        catch {
            return false;
        }
    }
    linuxDeleteKey(id) {
        try {
            (0, child_process_1.execSync)(`secret-tool clear service fivocell id "${id}"`, { encoding: 'utf-8', timeout: 5000, stdio: 'pipe' });
            return true;
        }
        catch {
            return false;
        }
    }
    // ============================================================
    // Unified interface
    // ============================================================
    getKey(id) {
        switch (this.osType) {
            case 'windows': return this.windowsGetKey(id);
            case 'macos': return this.macosGetKey(id);
            case 'linux': return this.linuxGetKey(id);
            default: return null;
        }
    }
    setKey(id, key) {
        switch (this.osType) {
            case 'windows': return this.windowsSetKey(id, key);
            case 'macos': return this.macosSetKey(id, key);
            case 'linux': return this.linuxSetKey(id, key);
            default: return false;
        }
    }
    deleteKey(id) {
        switch (this.osType) {
            case 'windows': return this.windowsDeleteKey(id);
            case 'macos': return this.macosDeleteKey(id);
            case 'linux': return this.linuxDeleteKey(id);
            default: return false;
        }
    }
}
exports.OSKeyProvider = OSKeyProvider;
//# sourceMappingURL=key-provider-os.js.map