"use strict";
/**
 * Image Analyzer Profile Hook Injector
 *
 * Injects image analyzer hooks into per-profile settings files.
 * This replaces the global ~/.claude/settings.json approach.
 *
 * Injects for profiles that resolve to a supported image-analysis backend.
 *
 * @module utils/hooks/image-analyzer-profile-injector
 */
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;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.removeMigrationMarker = exports.ensureProfileHooks = exports.removeImageAnalysisProfileHook = exports.hasImageAnalysisProfileHook = exports.getImageAnalysisProfileSettingsPath = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ui_1 = require("../ui");
const image_analyzer_hook_configuration_1 = require("./image-analyzer-hook-configuration");
const image_analyzer_hook_utils_1 = require("./image-analyzer-hook-utils");
const config_manager_1 = require("../config-manager");
const image_analysis_backend_resolver_1 = require("./image-analysis-backend-resolver");
const config_loader_facade_1 = require("../../config/config-loader-facade");
// Valid profile name pattern (alphanumeric, dot, dash, underscore only)
const VALID_PROFILE_NAME = /^[a-zA-Z0-9][a-zA-Z0-9._-]*$/;
/**
 * Get migration marker path (respects CCS_HOME for test isolation)
 */
function getMigrationMarkerPath() {
    return path.join((0, config_manager_1.getCcsDir)(), '.image-analyzer-hook-migrated');
}
/**
 * Check if CCS image analyzer hook exists in settings
 */
function hasCcsHook(settings) {
    const hooks = settings.hooks;
    if (!hooks?.PreToolUse)
        return false;
    return hooks.PreToolUse.some((h) => {
        return (0, image_analyzer_hook_utils_1.isCcsImageAnalyzerHook)(h);
    });
}
function getImageAnalysisProfileSettingsPath(profileName, settingsPath) {
    if (typeof settingsPath === 'string' && settingsPath.trim().length > 0) {
        return settingsPath;
    }
    return path.join((0, config_manager_1.getCcsDir)(), `${profileName}.settings.json`);
}
exports.getImageAnalysisProfileSettingsPath = getImageAnalysisProfileSettingsPath;
function hasImageAnalysisProfileHook(profileName, settingsPath) {
    if (!VALID_PROFILE_NAME.test(profileName)) {
        return false;
    }
    const resolvedSettingsPath = getImageAnalysisProfileSettingsPath(profileName, settingsPath);
    if (!fs.existsSync(resolvedSettingsPath)) {
        return false;
    }
    try {
        const content = fs.readFileSync(resolvedSettingsPath, 'utf8');
        const settings = JSON.parse(content);
        return hasCcsHook(settings);
    }
    catch {
        return false;
    }
}
exports.hasImageAnalysisProfileHook = hasImageAnalysisProfileHook;
function removeImageAnalysisProfileHook(profileName, settingsPath) {
    if (!VALID_PROFILE_NAME.test(profileName)) {
        return false;
    }
    const resolvedSettingsPath = getImageAnalysisProfileSettingsPath(profileName, settingsPath);
    if (!fs.existsSync(resolvedSettingsPath)) {
        return false;
    }
    try {
        const content = fs.readFileSync(resolvedSettingsPath, 'utf8');
        const settings = JSON.parse(content);
        const removed = (0, image_analyzer_hook_utils_1.removeCcsImageAnalyzerHooks)(settings);
        if (!removed) {
            return false;
        }
        fs.writeFileSync(resolvedSettingsPath, JSON.stringify(settings, null, 2), 'utf8');
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.info)(`Removed image analyzer hook from ${path.basename(resolvedSettingsPath)}`));
        }
        return true;
    }
    catch {
        return false;
    }
}
exports.removeImageAnalysisProfileHook = removeImageAnalysisProfileHook;
/**
 * One-time migration marker management
 */
function migrateGlobalHook() {
    const markerPath = getMigrationMarkerPath();
    if (fs.existsSync(markerPath)) {
        return; // Already migrated
    }
    try {
        // No global hook to migrate (image analyzer is profile-only from the start)
        // Just create marker to prevent future migration attempts
        const ccsDir = (0, config_manager_1.getCcsDir)();
        if (!fs.existsSync(ccsDir)) {
            fs.mkdirSync(ccsDir, { recursive: true, mode: 0o700 });
        }
        // Create marker file atomically (wx = fail if exists, prevents race condition)
        fs.writeFileSync(markerPath, new Date().toISOString(), { encoding: 'utf8', flag: 'wx' });
    }
    catch (error) {
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.warn)(`Migration failed: ${error.message}`));
        }
    }
}
/**
 * Ensure image analyzer hook is configured in profile's settings file
 *
 * @param input - Profile name or pre-resolved runtime context
 * @returns true if hook is configured (existing or newly added)
 */
function ensureProfileHooks(input) {
    try {
        const context = typeof input === 'string' ? { profileName: input } : input;
        const profileName = context.profileName;
        // Validate profile name to prevent path traversal
        if (!VALID_PROFILE_NAME.test(profileName)) {
            if (process.env.CCS_DEBUG) {
                console.error((0, ui_1.warn)(`Invalid profile name: ${profileName}`));
            }
            return false;
        }
        const imageConfig = (0, config_loader_facade_1.getImageAnalysisConfig)();
        const status = (0, image_analysis_backend_resolver_1.resolveImageAnalysisStatus)(context, imageConfig);
        if (!status.supported || !status.shouldPersistHook) {
            return false;
        }
        if (context.sharedHookInstalled === false) {
            return false;
        }
        // One-time migration marker
        migrateGlobalHook();
        // Get CCS directory (respects CCS_HOME for test isolation)
        const ccsDir = (0, config_manager_1.getCcsDir)();
        // Ensure CCS dir exists
        if (!fs.existsSync(ccsDir)) {
            fs.mkdirSync(ccsDir, { recursive: true, mode: 0o700 });
        }
        const settingsPath = getImageAnalysisProfileSettingsPath(profileName, context.settingsPath);
        // Read existing settings or create empty
        let settings = {};
        if (fs.existsSync(settingsPath)) {
            try {
                const content = fs.readFileSync(settingsPath, 'utf8');
                settings = JSON.parse(content);
            }
            catch (parseError) {
                if (process.env.CCS_DEBUG) {
                    console.error((0, ui_1.warn)(`Malformed ${profileName}.settings.json: ${parseError.message}`));
                }
                // Never overwrite malformed settings files; avoid destructive data loss.
                return false;
            }
        }
        // Check if CCS hook already present
        if (hasCcsHook(settings)) {
            const hadDuplicates = (0, image_analyzer_hook_utils_1.deduplicateCcsImageAnalyzerHooks)(settings);
            if (hadDuplicates) {
                fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
            }
            // Update timeout if needed
            return updateHookTimeoutIfNeeded(settings, settingsPath);
        }
        // Get hook config
        const hookConfig = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookConfig)();
        // Ensure hooks structure exists
        if (!settings.hooks) {
            settings.hooks = {};
        }
        const settingsHooks = settings.hooks;
        if (!settingsHooks.PreToolUse) {
            settingsHooks.PreToolUse = [];
        }
        // Add CCS hook
        const preToolUseHooks = hookConfig.PreToolUse;
        settingsHooks.PreToolUse.push(...preToolUseHooks);
        // Write updated settings
        fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.info)(`Added image analyzer hook to ${profileName}.settings.json`));
        }
        return true;
    }
    catch (error) {
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.warn)(`Failed to inject hook: ${error.message}`));
        }
        return false;
    }
}
exports.ensureProfileHooks = ensureProfileHooks;
/**
 * Update hook timeout if it differs from current config
 */
function updateHookTimeoutIfNeeded(settings, settingsPath) {
    try {
        const hooks = settings.hooks;
        const hookConfig = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookConfig)();
        const expectedHookPath = (0, image_analyzer_hook_configuration_1.getImageAnalyzerHookPath)();
        const expectedCommand = `node "${expectedHookPath}"`;
        const expectedHooks = hookConfig.PreToolUse[0]
            .hooks;
        const expectedTimeout = expectedHooks[0].timeout;
        let needsUpdate = false;
        for (const h of hooks.PreToolUse) {
            const hook = h;
            if (hook.matcher !== 'Read')
                continue;
            const hookArray = hook.hooks;
            if (!hookArray?.[0]?.command)
                continue;
            const command = hookArray[0].command;
            if (typeof command !== 'string')
                continue;
            // Normalize path separators for cross-platform matching (Windows uses backslashes)
            const normalizedCommand = command
                .replace(/\\/g, '/') // Windows backslashes
                .replace(/\/+/g, '/'); // Collapse multiple slashes
            if (!normalizedCommand.includes('.ccs/hooks/image-analyzer-transformer'))
                continue;
            // Found CCS hook - check if needs update
            if (hookArray[0].command !== expectedCommand) {
                hookArray[0].command = expectedCommand;
                needsUpdate = true;
            }
            if (hookArray[0].timeout !== expectedTimeout) {
                hookArray[0].timeout = expectedTimeout;
                needsUpdate = true;
            }
        }
        if (needsUpdate) {
            fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
            if (process.env.CCS_DEBUG) {
                console.error((0, ui_1.info)('Updated image analyzer hook timeout in profile settings'));
            }
        }
        return true;
    }
    catch (error) {
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.warn)(`updateHookTimeoutIfNeeded failed: ${error.message}`));
        }
        return false;
    }
}
/**
 * Remove migration marker (called during uninstall)
 */
function removeMigrationMarker() {
    try {
        const markerPath = getMigrationMarkerPath();
        if (fs.existsSync(markerPath)) {
            fs.unlinkSync(markerPath);
        }
    }
    catch (error) {
        if (process.env.CCS_DEBUG) {
            console.error((0, ui_1.warn)(`removeMigrationMarker failed: ${error.message}`));
        }
    }
}
exports.removeMigrationMarker = removeMigrationMarker;
//# sourceMappingURL=image-analyzer-profile-hook-injector.js.map