"use strict";
/**
 * Symlink and Permission Health Checks
 */
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.runSymlinkChecks = exports.SettingsSymlinksChecker = exports.CcsSymlinksChecker = exports.PermissionsChecker = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const ui_1 = require("../../utils/ui");
const types_1 = require("./types");
const config_loader_facade_1 = require("../../config/config-loader-facade");
const instance_directory_1 = require("../instance-directory");
const ora = (0, types_1.createSpinner)();
// Get paths at runtime to respect CCS_HOME for test isolation
function getHomedir() {
    return os.homedir();
}
function getCcsDirPath() {
    return (0, config_loader_facade_1.getCcsDir)();
}
function getClaudeDir() {
    return path.join(getHomedir(), '.claude');
}
/**
 * Check file permissions on ~/.ccs/
 */
class PermissionsChecker {
    constructor() {
        this.name = 'Permissions';
    }
    run(results) {
        const spinner = ora('Checking permissions').start();
        const testFile = path.join(getCcsDirPath(), '.permission-test');
        try {
            fs.writeFileSync(testFile, 'test', 'utf8');
            fs.unlinkSync(testFile);
            spinner.succeed();
            console.log(`  ${(0, ui_1.ok)('Permissions'.padEnd(22))}  Write access verified`);
            results.addCheck('Permissions', 'success', undefined, undefined, {
                status: 'OK',
                info: 'Write access verified',
            });
        }
        catch (_e) {
            spinner.fail();
            console.log(`  ${(0, ui_1.fail)('Permissions'.padEnd(22))}  Cannot write to ~/.ccs/`);
            results.addCheck('Permissions', 'error', 'Cannot write to ~/.ccs/', 'Fix: sudo chown -R $USER ~/.ccs ~/.claude && chmod 755 ~/.ccs ~/.claude', { status: 'ERROR', info: 'Cannot write to ~/.ccs/' });
        }
    }
}
exports.PermissionsChecker = PermissionsChecker;
/**
 * Check CCS symlinks to ~/.claude/
 */
class CcsSymlinksChecker {
    constructor() {
        this.name = 'CCS Symlinks';
    }
    run(results) {
        const spinner = ora('Checking CCS symlinks').start();
        try {
            const { ClaudeSymlinkManager } = require('../../utils/claude-symlink-manager');
            const manager = new ClaudeSymlinkManager();
            const health = manager.checkHealth();
            if (health.healthy) {
                const cnt = manager.ccsItems.length;
                spinner.succeed();
                console.log(`  ${(0, ui_1.ok)('CCS Symlinks'.padEnd(22))}  ${cnt}/${cnt} items linked`);
                results.addCheck('CCS Symlinks', 'success', 'All CCS items properly symlinked', undefined, {
                    status: 'OK',
                    info: `${cnt}/${cnt} items synced`,
                });
            }
            else {
                spinner.warn();
                console.log(`  ${(0, ui_1.warn)('CCS Symlinks'.padEnd(22))}  ${health.issues.length} issues found`);
                results.addCheck('CCS Symlinks', 'warning', health.issues.join(', '), 'Run: ccs sync', {
                    status: 'WARN',
                    info: `${health.issues.length} issues`,
                });
            }
        }
        catch (e) {
            spinner.warn();
            console.log(`  ${(0, ui_1.warn)('CCS Symlinks'.padEnd(22))}  Could not check`);
            results.addCheck('CCS Symlinks', 'warning', 'Could not check CCS symlinks: ' + e.message, 'Run: ccs sync', { status: 'WARN', info: 'Could not check' });
        }
    }
}
exports.CcsSymlinksChecker = CcsSymlinksChecker;
/** Helper: Check if symlink points to expected target */
function isValidSymlink(symlinkPath, expectedTarget) {
    if (!fs.existsSync(symlinkPath))
        return false;
    try {
        const stats = fs.lstatSync(symlinkPath);
        if (!stats.isSymbolicLink())
            return false;
        const target = fs.readlinkSync(symlinkPath);
        const resolved = path.resolve(path.dirname(symlinkPath), target);
        return resolved === expectedTarget;
    }
    catch {
        return false;
    }
}
/**
 * Check settings.json symlinks for instances
 */
class SettingsSymlinksChecker {
    constructor() {
        this.name = 'Settings Symlinks';
    }
    run(results) {
        const spinner = ora('Checking settings.json symlinks').start();
        const label = 'settings.json';
        const ccsDir = getCcsDirPath();
        const claudeDir = getClaudeDir();
        const sharedSettings = path.join(ccsDir, 'shared', 'settings.json');
        const claudeSettings = path.join(claudeDir, 'settings.json');
        try {
            // Check shared settings symlink
            if (!fs.existsSync(sharedSettings)) {
                spinner.warn();
                console.log(`  ${(0, ui_1.warn)(label.padEnd(22))}  Not found (shared)`);
                results.addCheck('Settings Symlinks', 'warning', 'Shared settings.json not found', 'Run: ccs sync');
                return;
            }
            const sharedStats = fs.lstatSync(sharedSettings);
            if (!sharedStats.isSymbolicLink()) {
                spinner.warn();
                console.log(`  ${(0, ui_1.warn)(label.padEnd(22))}  Not a symlink (shared)`);
                results.addCheck('Settings Symlinks', 'warning', 'Shared settings.json is not a symlink', 'Run: ccs sync');
                return;
            }
            if (!isValidSymlink(sharedSettings, claudeSettings)) {
                spinner.warn();
                console.log(`  ${(0, ui_1.warn)(label.padEnd(22))}  Wrong target (shared)`);
                results.addCheck('Settings Symlinks', 'warning', 'Shared symlink points to wrong target', 'Run: ccs sync');
                return;
            }
            // Check instances
            const instancesDir = path.join(ccsDir, 'instances');
            if (!fs.existsSync(instancesDir)) {
                spinner.succeed();
                console.log(`  ${(0, ui_1.ok)(label.padEnd(22))}  Shared symlink valid`);
                results.addCheck('Settings Symlinks', 'success', 'Shared symlink valid', undefined, {
                    status: 'OK',
                    info: 'Shared symlink valid',
                });
                return;
            }
            const instances = (0, instance_directory_1.listAccountInstanceNames)(instancesDir);
            const broken = instances.filter((inst) => {
                const instSettings = path.join(instancesDir, inst, 'settings.json');
                return !isValidSymlink(instSettings, sharedSettings);
            }).length;
            if (broken > 0) {
                spinner.warn();
                console.log(`  ${(0, ui_1.warn)(label.padEnd(22))}  ${broken} broken instance(s)`);
                results.addCheck('Settings Symlinks', 'warning', `${broken} instance(s) have broken symlinks`, 'Run: ccs sync', { status: 'WARN', info: `${broken} broken instance(s)` });
            }
            else {
                spinner.succeed();
                console.log(`  ${(0, ui_1.ok)(label.padEnd(22))}  ${instances.length} instance(s) valid`);
                results.addCheck('Settings Symlinks', 'success', 'All instance symlinks valid', undefined, {
                    status: 'OK',
                    info: `${instances.length} instance(s) valid`,
                });
            }
        }
        catch (err) {
            spinner.warn();
            console.log(`  ${(0, ui_1.warn)(label.padEnd(22))}  Check failed`);
            results.addCheck('Settings Symlinks', 'warning', `Failed to check: ${err.message}`, 'Run: ccs sync', { status: 'WARN', info: 'Check failed' });
        }
    }
}
exports.SettingsSymlinksChecker = SettingsSymlinksChecker;
/**
 * Run all symlink checks
 */
function runSymlinkChecks(results) {
    new PermissionsChecker().run(results);
    new CcsSymlinksChecker().run(results);
    new SettingsSymlinksChecker().run(results);
}
exports.runSymlinkChecks = runSymlinkChecks;
//# sourceMappingURL=symlink-check.js.map