"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.deleteClaudeExtensionBinding = exports.updateClaudeExtensionBinding = exports.createClaudeExtensionBinding = exports.updateClaudeExtensionManagedEnvManifest = exports.getClaudeExtensionManagedEnvManifest = exports.getClaudeExtensionBinding = exports.listClaudeExtensionBindings = void 0;
const crypto_1 = require("crypto");
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const profile_detector_1 = __importDefault(require("../../auth/profile-detector"));
const helpers_1 = require("../../utils/helpers");
const config_loader_facade_1 = require("../../config/config-loader-facade");
const VALID_HOSTS = new Set(['vscode', 'cursor', 'windsurf']);
function getBindingsFilePath() {
    return path.join((0, config_loader_facade_1.getCcsDir)(), 'claude-extension-bindings.json');
}
function isRecord(value) {
    return typeof value === 'object' && value !== null && !Array.isArray(value);
}
function normalizeEnvKeyList(value) {
    if (!Array.isArray(value))
        return [];
    return [...new Set(value.filter((entry) => typeof entry === 'string'))]
        .map((entry) => entry.trim())
        .filter(Boolean)
        .sort((left, right) => left.localeCompare(right));
}
function normalizeManagedEnvManifest(value) {
    if (!isRecord(value)) {
        return { shared: [], ide: [] };
    }
    return {
        shared: normalizeEnvKeyList(value.shared),
        ide: normalizeEnvKeyList(value.ide),
    };
}
function toPublicBinding(binding) {
    const { managedEnvManifest: _managedEnvManifest, ...publicBinding } = binding;
    return publicBinding;
}
function normalizeBindingInput(input) {
    const name = input.name?.trim();
    const profile = input.profile?.trim();
    const ideSettingsPath = input.ideSettingsPath?.trim();
    const notes = input.notes?.trim();
    if (!name)
        throw new Error('Binding name is required');
    if (!profile)
        throw new Error('Profile is required');
    if (!VALID_HOSTS.has(input.host))
        throw new Error(`Unsupported IDE host "${input.host}"`);
    try {
        new profile_detector_1.default().detectProfileType(profile);
    }
    catch {
        throw new Error(`Unknown profile "${profile}"`);
    }
    return {
        name,
        profile,
        host: input.host,
        ideSettingsPath: ideSettingsPath ? (0, helpers_1.expandPath)(ideSettingsPath) : undefined,
        notes: notes || undefined,
    };
}
function normalizeStoredBinding(value) {
    if (!isRecord(value))
        return null;
    const id = typeof value.id === 'string' ? value.id.trim() : '';
    const name = typeof value.name === 'string' ? value.name.trim() : '';
    const profile = typeof value.profile === 'string' ? value.profile.trim() : '';
    const host = typeof value.host === 'string' ? value.host.trim() : '';
    const createdAt = typeof value.createdAt === 'string' ? value.createdAt : '';
    const updatedAt = typeof value.updatedAt === 'string' ? value.updatedAt : '';
    if (!id || !name || !profile || !VALID_HOSTS.has(host)) {
        return null;
    }
    return {
        id,
        name,
        profile,
        host: host,
        ideSettingsPath: typeof value.ideSettingsPath === 'string' && value.ideSettingsPath.trim().length > 0
            ? value.ideSettingsPath.trim()
            : undefined,
        notes: typeof value.notes === 'string' && value.notes.trim().length > 0
            ? value.notes.trim()
            : undefined,
        createdAt: createdAt || new Date().toISOString(),
        updatedAt: updatedAt || new Date().toISOString(),
        managedEnvManifest: normalizeManagedEnvManifest(value.managedEnvManifest),
    };
}
function readBindingsStore() {
    const filePath = getBindingsFilePath();
    if (!fs.existsSync(filePath)) {
        return { bindings: [] };
    }
    const raw = fs.readFileSync(filePath, 'utf8');
    let parsed;
    try {
        parsed = JSON.parse(raw);
    }
    catch (error) {
        throw new Error(`Failed to parse Claude extension bindings store at ${filePath}: ${error.message}`);
    }
    const bindings = Array.isArray(parsed)
        ? parsed
        : isRecord(parsed) && Array.isArray(parsed.bindings)
            ? parsed.bindings
            : [];
    return {
        bindings: bindings
            .map((entry) => normalizeStoredBinding(entry))
            .filter((entry) => entry !== null)
            .sort((left, right) => right.updatedAt.localeCompare(left.updatedAt)),
    };
}
function writeBindingsStore(store) {
    const filePath = getBindingsFilePath();
    fs.mkdirSync(path.dirname(filePath), { recursive: true });
    const tempPath = `${filePath}.tmp.${process.pid}-${Date.now()}-${(0, crypto_1.randomUUID)()}`;
    try {
        fs.writeFileSync(tempPath, JSON.stringify(store, null, 2) + '\n', 'utf8');
        fs.renameSync(tempPath, filePath);
    }
    catch (error) {
        if (fs.existsSync(tempPath)) {
            fs.rmSync(tempPath, { force: true });
        }
        throw error;
    }
}
function listClaudeExtensionBindings() {
    return readBindingsStore().bindings.map((binding) => toPublicBinding(binding));
}
exports.listClaudeExtensionBindings = listClaudeExtensionBindings;
function getClaudeExtensionBinding(id) {
    const binding = readBindingsStore().bindings.find((entry) => entry.id === id);
    if (!binding) {
        throw new Error(`Binding not found: ${id}`);
    }
    return toPublicBinding(binding);
}
exports.getClaudeExtensionBinding = getClaudeExtensionBinding;
function getClaudeExtensionManagedEnvManifest(id) {
    const binding = readBindingsStore().bindings.find((entry) => entry.id === id);
    if (!binding) {
        throw new Error(`Binding not found: ${id}`);
    }
    return binding.managedEnvManifest;
}
exports.getClaudeExtensionManagedEnvManifest = getClaudeExtensionManagedEnvManifest;
function updateClaudeExtensionManagedEnvManifest(id, updates) {
    const store = readBindingsStore();
    const index = store.bindings.findIndex((entry) => entry.id === id);
    if (index === -1) {
        throw new Error(`Binding not found: ${id}`);
    }
    const current = store.bindings[index];
    store.bindings[index] = {
        ...current,
        managedEnvManifest: {
            shared: updates.shared !== undefined
                ? normalizeEnvKeyList(updates.shared)
                : current.managedEnvManifest.shared,
            ide: updates.ide !== undefined
                ? normalizeEnvKeyList(updates.ide)
                : current.managedEnvManifest.ide,
        },
    };
    writeBindingsStore(store);
}
exports.updateClaudeExtensionManagedEnvManifest = updateClaudeExtensionManagedEnvManifest;
function createClaudeExtensionBinding(input) {
    const normalized = normalizeBindingInput(input);
    const store = readBindingsStore();
    const timestamp = new Date().toISOString();
    const binding = {
        managedEnvManifest: { shared: [], ide: [] },
        id: (0, crypto_1.randomUUID)(),
        createdAt: timestamp,
        updatedAt: timestamp,
        ...normalized,
    };
    store.bindings.unshift(binding);
    writeBindingsStore(store);
    return toPublicBinding(binding);
}
exports.createClaudeExtensionBinding = createClaudeExtensionBinding;
function updateClaudeExtensionBinding(id, input) {
    const normalized = normalizeBindingInput(input);
    const store = readBindingsStore();
    const index = store.bindings.findIndex((entry) => entry.id === id);
    if (index === -1) {
        throw new Error(`Binding not found: ${id}`);
    }
    const updated = {
        ...store.bindings[index],
        ...normalized,
        updatedAt: new Date().toISOString(),
    };
    store.bindings[index] = updated;
    writeBindingsStore(store);
    return toPublicBinding(updated);
}
exports.updateClaudeExtensionBinding = updateClaudeExtensionBinding;
function deleteClaudeExtensionBinding(id) {
    const store = readBindingsStore();
    const nextBindings = store.bindings.filter((entry) => entry.id !== id);
    if (nextBindings.length === store.bindings.length) {
        throw new Error(`Binding not found: ${id}`);
    }
    writeBindingsStore({ bindings: nextBindings });
}
exports.deleteClaudeExtensionBinding = deleteClaudeExtensionBinding;
//# sourceMappingURL=claude-extension-binding-service.js.map