import { readFileSync, existsSync } from 'node:fs';
import { execSync } from 'node:child_process';
import { join } from 'node:path';
import { config as loadEnv } from 'dotenv';
import { getConfigDir } from '../../shared/services/configDir.js';
import { isReviewFocus, reviewSkillForFocus, } from '../../modules/review-execution/entities/progress/reviewFocus.type.js';
const configDir = getConfigDir();
const xdgEnvPath = join(configDir, '.env');
if (existsSync(xdgEnvPath)) {
    loadEnv({ path: xdgEnvPath });
}
else {
    loadEnv();
}
function loadProjectConfig(localPath) {
    const configPath = join(localPath, '.claude', 'reviews', 'config.json');
    if (!existsSync(configPath)) {
        return null;
    }
    try {
        const content = readFileSync(configPath, 'utf-8');
        const parsed = JSON.parse(content);
        const result = {};
        if (typeof parsed.github === 'boolean') {
            result.github = parsed.github;
        }
        if (typeof parsed.gitlab === 'boolean') {
            result.gitlab = parsed.gitlab;
        }
        if (typeof parsed.reviewSkill === 'string') {
            result.reviewSkill = parsed.reviewSkill;
        }
        if (isReviewFocus(parsed.reviewFocus)) {
            result.reviewFocus = parsed.reviewFocus;
        }
        return result;
    }
    catch {
        return null;
    }
}
export function normalizeGitUrl(url) {
    // Convert SSH URLs (git@host:org/repo.git) to HTTPS (https://host/org/repo)
    const sshMatch = url.match(/^git@([^:]+):(.+)$/);
    if (sshMatch) {
        return `https://${sshMatch[1]}/${sshMatch[2].replace(/\.git$/, '')}`;
    }
    return url.replace(/\.git$/, '');
}
function getGitRemoteUrl(localPath) {
    try {
        const result = execSync('git remote get-url origin', {
            cwd: localPath,
            encoding: 'utf-8',
            timeout: 5000,
        });
        return normalizeGitUrl(result.trim());
    }
    catch {
        return null;
    }
}
function enrichRepository(input) {
    const projectConfig = loadProjectConfig(input.localPath);
    const remoteUrl = getGitRemoteUrl(input.localPath);
    if (!projectConfig) {
        console.warn(`[config] Pas de config projet pour ${input.name} (${input.localPath})`);
        return null;
    }
    if (!remoteUrl) {
        console.warn(`[config] Pas de remote git pour ${input.name} (${input.localPath})`);
        return null;
    }
    const platform = projectConfig.gitlab ? 'gitlab' : 'github';
    const skill = projectConfig.reviewSkill ||
        (projectConfig.reviewFocus ? reviewSkillForFocus(projectConfig.reviewFocus) : 'review-code');
    return {
        name: input.name,
        platform,
        remoteUrl,
        localPath: input.localPath,
        skill,
        enabled: input.enabled,
    };
}
export function enrichSingleRepository(input) {
    const projectConfig = loadProjectConfig(input.localPath);
    const remoteUrl = getGitRemoteUrl(input.localPath);
    const platform = projectConfig?.gitlab ? 'gitlab' : 'github';
    const skill = projectConfig?.reviewSkill ||
        (projectConfig?.reviewFocus ? reviewSkillForFocus(projectConfig.reviewFocus) : 'review-code');
    return {
        name: input.name,
        platform,
        remoteUrl: remoteUrl ?? '',
        localPath: input.localPath,
        skill,
        enabled: input.enabled,
    };
}
export function validateAndEnrichConfig(data) {
    if (!data || typeof data !== 'object') {
        throw new Error('Configuration invalide : objet attendu');
    }
    const config = data;
    // Validate server
    if (!config.server || typeof config.server !== 'object') {
        throw new Error('Configuration invalide : section "server" manquante');
    }
    const server = config.server;
    if (typeof server.port !== 'number' || server.port < 1 || server.port > 65535) {
        throw new Error('Configuration invalide : port invalide');
    }
    // Validate user
    if (!config.user || typeof config.user !== 'object') {
        throw new Error('Configuration invalide : section "user" manquante');
    }
    const user = config.user;
    if (typeof user.gitlabUsername !== 'string') {
        throw new Error('Invalid configuration: gitlabUsername must be a string');
    }
    if (typeof user.githubUsername !== 'string') {
        throw new Error('Invalid configuration: githubUsername must be a string');
    }
    // Validate queue
    if (!config.queue || typeof config.queue !== 'object') {
        throw new Error('Configuration invalide : section "queue" manquante');
    }
    const queue = config.queue;
    if (typeof queue.maxConcurrent !== 'number' || queue.maxConcurrent < 1) {
        throw new Error('Configuration invalide : maxConcurrent invalide');
    }
    if (typeof queue.deduplicationWindowMs !== 'number' || queue.deduplicationWindowMs < 0) {
        throw new Error('Configuration invalide : deduplicationWindowMs invalide');
    }
    let jobHistoryRetentionDays = 7;
    if (queue.jobHistoryRetentionDays !== undefined && queue.jobHistoryRetentionDays !== null) {
        if (typeof queue.jobHistoryRetentionDays !== 'number' ||
            !Number.isInteger(queue.jobHistoryRetentionDays) ||
            queue.jobHistoryRetentionDays < 1 ||
            queue.jobHistoryRetentionDays > 365) {
            throw new Error('Configuration invalide : jobHistoryRetentionDays invalide');
        }
        jobHistoryRetentionDays = queue.jobHistoryRetentionDays;
    }
    // Validate triggerMode (optional, defaults to 'full-auto')
    let triggerMode = 'full-auto';
    if (config.triggerMode !== undefined && config.triggerMode !== null) {
        if (config.triggerMode !== 'full-auto' && config.triggerMode !== 'semi-auto') {
            throw new Error('Mode de déclenchement invalide : valeurs autorisées « full-auto » ou « semi-auto »');
        }
        triggerMode = config.triggerMode;
    }
    // Validate and enrich repositories
    if (!Array.isArray(config.repositories)) {
        throw new Error('Configuration invalide : repositories doit être un tableau');
    }
    const enrichedRepositories = [];
    for (const repo of config.repositories) {
        if (!repo || typeof repo !== 'object') {
            throw new Error('Configuration invalide : repository invalide');
        }
        const r = repo;
        if (typeof r.name !== 'string' || !r.name) {
            throw new Error('Configuration invalide : name manquant');
        }
        if (typeof r.localPath !== 'string' || !r.localPath) {
            throw new Error('Configuration invalide : localPath manquant');
        }
        if (typeof r.enabled !== 'boolean') {
            throw new Error('Configuration invalide : enabled doit être un booléen');
        }
        const input = {
            name: r.name,
            localPath: r.localPath,
            enabled: r.enabled,
        };
        const enriched = enrichRepository(input);
        if (enriched) {
            enrichedRepositories.push(enriched);
        }
    }
    return {
        server: { port: server.port },
        user: {
            gitlabUsername: user.gitlabUsername,
            githubUsername: user.githubUsername,
        },
        queue: {
            maxConcurrent: queue.maxConcurrent,
            deduplicationWindowMs: queue.deduplicationWindowMs,
            jobHistoryRetentionDays,
        },
        repositories: enrichedRepositories,
        triggerMode,
    };
}
function loadSecrets() {
    const gitlabWebhookToken = process.env.GITLAB_WEBHOOK_TOKEN;
    const githubWebhookSecret = process.env.GITHUB_WEBHOOK_SECRET;
    if (!gitlabWebhookToken) {
        throw new Error('Variable d\'environnement GITLAB_WEBHOOK_TOKEN manquante');
    }
    if (!githubWebhookSecret) {
        throw new Error('Variable d\'environnement GITHUB_WEBHOOK_SECRET manquante');
    }
    return { gitlabWebhookToken, githubWebhookSecret };
}
// Main loader
let cachedConfig = null;
let cachedSecrets = null;
function resolveConfigPath() {
    if (process.env.CONFIG_PATH)
        return process.env.CONFIG_PATH;
    const cwdPath = join(process.cwd(), 'config.json');
    if (existsSync(cwdPath))
        return cwdPath;
    const xdgPath = join(configDir, 'config.json');
    if (existsSync(xdgPath))
        return xdgPath;
    return cwdPath;
}
export function resolveActiveConfigPath() {
    return resolveConfigPath();
}
export function loadConfig() {
    if (cachedConfig)
        return cachedConfig;
    const configPath = resolveConfigPath();
    if (!existsSync(configPath)) {
        throw new Error(`Configuration file not found: ${configPath}\nRun 'reviewflow init' to create one.`);
    }
    const rawContent = readFileSync(configPath, 'utf-8');
    const parsed = JSON.parse(rawContent);
    cachedConfig = validateAndEnrichConfig(parsed);
    return cachedConfig;
}
export function loadEnvSecrets() {
    if (cachedSecrets)
        return cachedSecrets;
    cachedSecrets = loadSecrets();
    return cachedSecrets;
}
export function findRepositoryByRemoteUrl(remoteUrl) {
    const config = loadConfig();
    const normalizeUrl = (url) => url.replace(/\.git$/, '').replace(/\/$/, '').toLowerCase();
    const normalizedInput = normalizeUrl(remoteUrl);
    return config.repositories.find(repo => repo.enabled && normalizeUrl(repo.remoteUrl) === normalizedInput);
}
export function findRepositoryByProjectPath(projectPath) {
    const config = loadConfig();
    const normalizedPath = projectPath.toLowerCase();
    return config.repositories.find(repo => {
        if (!repo.enabled)
            return false;
        const urlPath = repo.remoteUrl
            .replace(/^https?:\/\/[^/]+\//, '')
            .replace(/\.git$/, '')
            .toLowerCase();
        return urlPath === normalizedPath;
    });
}
//# sourceMappingURL=configLoader.js.map