import fs from 'node:fs/promises';
import os from 'node:os';
import path from 'node:path';
import { loadRawConfig, resolveConfigPath } from '../../config.js';
import { CliUsageError } from '../errors.js';
import { chooseClosestIdentifier, renderIdentifierResolutionMessages } from '../identifier-helpers.js';
import { dimText, supportsAnsiColor } from '../terminal.js';
export const COLOR_ENABLED = () => Boolean(supportsAnsiColor && process.stdout.isTTY);
export function cloneConfig(config) {
    return {
        mcpServers: config.mcpServers ? { ...config.mcpServers } : {},
        imports: config.imports ? [...config.imports] : [],
    };
}
export async function loadOrCreateConfig(loadOptions) {
    try {
        const { config, path } = await loadRawConfig(loadOptions);
        return { config, path };
    }
    catch (error) {
        if (isErrno(error, 'ENOENT')) {
            const rootDir = loadOptions.rootDir ?? process.cwd();
            const resolved = resolveConfigPath(loadOptions.configPath, rootDir);
            return { config: { mcpServers: {}, imports: [] }, path: resolved.path };
        }
        throw error;
    }
}
export async function resolveConfigLocations(loadOptions) {
    const rootDir = loadOptions.rootDir ?? process.cwd();
    const projectPath = path.resolve(rootDir, 'config', 'mcporter.json');
    const projectExists = await pathExists(projectPath);
    const systemCandidates = buildSystemConfigCandidates();
    const systemResolved = await resolveFirstExisting(systemCandidates);
    return {
        projectPath,
        projectExists,
        systemPath: systemResolved.path,
        systemExists: systemResolved.exists,
    };
}
export function logConfigLocations(summary, options) {
    const shouldAddNewline = options?.leadingNewline ?? true;
    if (shouldAddNewline) {
        console.log('');
    }
    console.log(`Project config: ${formatPath(summary.projectPath, summary.projectExists)}`);
    console.log(`System config: ${formatPath(summary.systemPath, summary.systemExists)}`);
}
export function findServerNameWithFuzzyMatch(name, candidates, logger = console.log) {
    if (candidates.includes(name)) {
        return name;
    }
    const resolution = chooseClosestIdentifier(name, candidates);
    if (!resolution) {
        return null;
    }
    const messages = renderIdentifierResolutionMessages({
        entity: 'server',
        attempted: name,
        resolution,
    });
    if (messages.auto && logger) {
        logger(dimText(messages.auto));
    }
    if (resolution.kind === 'auto') {
        return resolution.value;
    }
    if (messages.suggest && logger) {
        logger(dimText(messages.suggest));
    }
    return null;
}
export function resolveServerDefinition(name, servers, logger = console.log) {
    const direct = servers.find((server) => server.name === name);
    if (direct) {
        return direct;
    }
    const resolution = chooseClosestIdentifier(name, servers.map((server) => server.name));
    if (!resolution) {
        throw new CliUsageError(`[mcporter] Unknown server '${name}'.`);
    }
    const messages = renderIdentifierResolutionMessages({
        entity: 'server',
        attempted: name,
        resolution,
    });
    if (messages.auto && logger) {
        logger(dimText(messages.auto));
    }
    if (resolution.kind === 'auto') {
        const match = servers.find((server) => server.name === resolution.value);
        if (match) {
            return match;
        }
    }
    if (messages.suggest && logger) {
        logger(dimText(messages.suggest));
    }
    throw new CliUsageError(`[mcporter] Unknown server '${name}'.`);
}
function buildSystemConfigCandidates() {
    const homeDir = os.homedir();
    const base = path.join(homeDir, '.mcporter');
    return [path.join(base, 'mcporter.json'), path.join(base, 'mcporter.jsonc')];
}
async function resolveFirstExisting(pathsToCheck) {
    for (const candidate of pathsToCheck) {
        if (await pathExists(candidate)) {
            return { path: candidate, exists: true };
        }
    }
    return { path: pathsToCheck[0] ?? '', exists: false };
}
async function pathExists(targetPath) {
    try {
        await fs.access(targetPath);
        return true;
    }
    catch {
        return false;
    }
}
function formatPath(targetPath, exists) {
    return exists ? targetPath : `${targetPath} (missing)`;
}
function isErrno(error, code) {
    return Boolean(error && typeof error === 'object' && error.code === code);
}
//# sourceMappingURL=shared.js.map