import { existsSync } from 'fs';
import { ClientError, resolvePath } from '../lib/index.js';
function isEnvTrue(envVar) {
    if (!envVar)
        return false;
    const normalized = envVar.toLowerCase().trim();
    return normalized === '1' || normalized === 'true' || normalized === 'yes';
}
export function getVerboseFromEnv() {
    return isEnvTrue(process.env.MCPC_VERBOSE);
}
export function getJsonFromEnv() {
    return isEnvTrue(process.env.MCPC_JSON);
}
const OPTIONS_WITH_VALUES = [
    '-c',
    '--config',
    '-H',
    '--header',
    '--timeout',
    '--profile',
    '--schema',
    '--schema-mode',
    '--proxy',
    '--proxy-bearer-token',
];
const KNOWN_OPTIONS = [
    ...OPTIONS_WITH_VALUES,
    '-j',
    '--json',
    '-v',
    '--version',
    '-h',
    '--help',
    '--verbose',
    '--clean',
    '--full',
];
const VALID_CLEAN_TYPES = ['sessions', 'profiles', 'logs', 'all'];
const VALID_SCHEMA_MODES = ['strict', 'compatible', 'ignore'];
export function optionTakesValue(arg) {
    const optionName = arg.includes('=') ? arg.substring(0, arg.indexOf('=')) : arg;
    return OPTIONS_WITH_VALUES.includes(optionName);
}
function isKnownOption(arg) {
    const optionName = arg.includes('=') ? arg.substring(0, arg.indexOf('=')) : arg;
    return KNOWN_OPTIONS.includes(optionName);
}
export function validateOptions(args) {
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        if (!arg)
            continue;
        if (arg.startsWith('-')) {
            if (!isKnownOption(arg)) {
                throw new ClientError(`Unknown option: ${arg}`);
            }
            if (optionTakesValue(arg) && !arg.includes('=') && i + 1 < args.length) {
                i++;
            }
        }
    }
}
export function validateCleanTypes(types) {
    for (const type of types) {
        if (type && !VALID_CLEAN_TYPES.includes(type)) {
            throw new ClientError(`Invalid --clean type: "${type}". Valid types are: ${VALID_CLEAN_TYPES.join(', ')}`);
        }
    }
}
export function validateArgValues(args) {
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        const nextArg = args[i + 1];
        if (!arg)
            continue;
        if (arg === '--schema-mode' && nextArg) {
            if (!VALID_SCHEMA_MODES.includes(nextArg)) {
                throw new ClientError(`Invalid --schema-mode value: "${nextArg}". Valid modes are: ${VALID_SCHEMA_MODES.join(', ')}`);
            }
        }
        if (arg === '--timeout' && nextArg) {
            const timeout = parseInt(nextArg, 10);
            if (isNaN(timeout) || timeout <= 0) {
                throw new ClientError(`Invalid --timeout value: "${nextArg}". Must be a positive number (seconds).`);
            }
        }
        if ((arg === '--config' || arg === '-c') && nextArg) {
            const configPath = resolvePath(nextArg);
            if (!existsSync(configPath)) {
                throw new ClientError(`Config file not found: ${nextArg}`);
            }
        }
        if (arg === '--schema' && nextArg) {
            const schemaPath = resolvePath(nextArg);
            if (!existsSync(schemaPath)) {
                throw new ClientError(`Schema file not found: ${nextArg}`);
            }
        }
        if (arg === '--proxy' && nextArg) {
            if (!nextArg.trim()) {
                throw new ClientError('--proxy requires a value in format [HOST:]PORT');
            }
        }
    }
}
export function findTarget(args) {
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        if (!arg)
            continue;
        if (arg.startsWith('-')) {
            if (optionTakesValue(arg) && !arg.includes('=') && i + 1 < args.length) {
                i++;
            }
            continue;
        }
        return { target: arg, targetIndex: i };
    }
    return undefined;
}
export function extractOptions(args) {
    const options = {
        verbose: args.includes('--verbose') || getVerboseFromEnv(),
        json: args.includes('--json') || args.includes('-j') || getJsonFromEnv(),
    };
    const configIndex = args.findIndex((arg) => arg === '--config' || arg === '-c');
    const config = configIndex >= 0 && configIndex + 1 < args.length ? args[configIndex + 1] : undefined;
    const headers = [];
    for (let i = 0; i < args.length; i++) {
        const arg = args[i];
        const nextArg = args[i + 1];
        if ((arg === '--header' || arg === '-H') && nextArg) {
            headers.push(nextArg);
        }
    }
    const timeoutIndex = args.findIndex((arg) => arg === '--timeout');
    const timeoutValue = timeoutIndex >= 0 && timeoutIndex + 1 < args.length ? args[timeoutIndex + 1] : undefined;
    const timeout = timeoutValue ? parseInt(timeoutValue, 10) : undefined;
    const profileIndex = args.findIndex((arg) => arg === '--profile');
    const profile = profileIndex >= 0 && profileIndex + 1 < args.length ? args[profileIndex + 1] : undefined;
    return {
        ...options,
        ...(config && { config }),
        ...(headers.length > 0 && { headers }),
        ...(timeout !== undefined && { timeout }),
        ...(profile && { profile }),
    };
}
export function hasCommandAfterTarget(args) {
    for (let i = 2; i < args.length; i++) {
        const arg = args[i];
        if (!arg)
            continue;
        if (arg.startsWith('-')) {
            if (optionTakesValue(arg) && !arg.includes('=')) {
                i++;
            }
            continue;
        }
        return true;
    }
    return false;
}
function autoParseValue(value) {
    try {
        return JSON.parse(value);
    }
    catch {
        return value;
    }
}
export function parseCommandArgs(args) {
    if (!args || args.length === 0) {
        return {};
    }
    const firstArg = args[0];
    if (firstArg && (firstArg.startsWith('{') || firstArg.startsWith('['))) {
        if (args.length > 1) {
            throw new ClientError('When using inline JSON, only one argument is allowed');
        }
        try {
            const parsedArgs = JSON.parse(firstArg);
            if (typeof parsedArgs !== 'object' || parsedArgs === null) {
                throw new ClientError('Inline JSON must be an object or array');
            }
            return parsedArgs;
        }
        catch (error) {
            if (error instanceof ClientError) {
                throw error;
            }
            throw new ClientError(`Invalid JSON: ${error.message}`);
        }
    }
    const parsedArgs = {};
    for (const pair of args) {
        if (!pair.includes(':=')) {
            throw new ClientError(`Invalid argument format: "${pair}". Use key:=value pairs or inline JSON.\n` +
                `Examples: name:=hello count:=10 enabled:=true '{"key":"value"}'`);
        }
        const colonEqualIndex = pair.indexOf(':=');
        const key = pair.substring(0, colonEqualIndex);
        const rawValue = pair.substring(colonEqualIndex + 2);
        if (!key) {
            throw new ClientError(`Invalid argument: "${pair}" - missing key before :=`);
        }
        parsedArgs[key] = autoParseValue(rawValue);
    }
    return parsedArgs;
}
export function hasStdinData() {
    return !process.stdin.isTTY;
}
export async function readStdinArgs() {
    return new Promise((resolve, reject) => {
        let data = '';
        process.stdin.setEncoding('utf-8');
        process.stdin.on('data', (chunk) => {
            data += chunk;
        });
        process.stdin.on('end', () => {
            if (!data.trim()) {
                resolve({});
                return;
            }
            try {
                const parsed = JSON.parse(data);
                if (typeof parsed !== 'object' || parsed === null) {
                    reject(new ClientError('Stdin must contain a JSON object'));
                    return;
                }
                resolve(parsed);
            }
            catch (error) {
                reject(new ClientError(`Invalid JSON from stdin: ${error.message}`));
            }
        });
        process.stdin.on('error', (error) => {
            reject(new ClientError(`Failed to read stdin: ${error.message}`));
        });
        process.stdin.resume();
    });
}
export function parseHeaderFlags(headerFlags) {
    const headers = {};
    if (headerFlags) {
        for (const header of headerFlags) {
            const colonIndex = header.indexOf(':');
            if (colonIndex < 1) {
                throw new ClientError(`Invalid header format: ${header}. Use "Key: Value"`);
            }
            const key = header.substring(0, colonIndex).trim();
            const value = header.substring(colonIndex + 1).trim();
            headers[key] = value;
        }
    }
    return headers;
}
export function parseProxyArg(value) {
    const DEFAULT_HOST = '127.0.0.1';
    const lastColonIndex = value.lastIndexOf(':');
    if (lastColonIndex === -1) {
        const port = parseInt(value, 10);
        if (isNaN(port) || port <= 0 || port > 65535) {
            throw new ClientError(`Invalid --proxy port: "${value}". Must be a number between 1 and 65535.`);
        }
        return { host: DEFAULT_HOST, port };
    }
    const host = value.substring(0, lastColonIndex);
    const portStr = value.substring(lastColonIndex + 1);
    const port = parseInt(portStr, 10);
    if (!host) {
        throw new ClientError(`Invalid --proxy format: "${value}". Host cannot be empty.`);
    }
    if (isNaN(port) || port <= 0 || port > 65535) {
        throw new ClientError(`Invalid --proxy port: "${portStr}". Must be a number between 1 and 65535.`);
    }
    return { host, port };
}
//# sourceMappingURL=parser.js.map