"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const chalk_1 = __importDefault(require("chalk"));
const config_storage_1 = require("../../lib/config-storage");
const key_router_1 = require("../../config/key-router");
const preferences_schema_1 = require("../../config/preferences-schema");
const preferences_resolver_1 = require("../../config/preferences-resolver");
const provider_credential_schemas_1 = require("../../lib/provider-credential-schemas");
const prompts_1 = require("../../lib/prompts");
const scaleway_validator_1 = require("../../lib/scaleway-validator");
class ConfigSet extends core_1.Command {
    async run() {
        const { args } = await this.parse(ConfigSet);
        try {
            const storage = new config_storage_1.ConfigStorage();
            const kind = (0, key_router_1.classifyKey)(args.key);
            switch (kind) {
                case 'preference':
                    if (!args.value) {
                        console.log(chalk_1.default.red(`\nMissing value for preference '${args.key}'\n`));
                        this.exit(1);
                    }
                    this.setPreference(storage, args.key, args.value);
                    return;
                case 'provider':
                    await this.setProvider(storage, args.key.toLowerCase(), args.value);
                    return;
                case 'system':
                    if (!args.value) {
                        console.log(chalk_1.default.red(`\nMissing value for '${args.key}'\n`));
                        this.exit(1);
                    }
                    this.setSystem(storage, args.key.toLowerCase(), args.value);
                    return;
                case 'unknown':
                    this.failUnknown(args.key);
                    return;
            }
        }
        catch (error) {
            console.log(chalk_1.default.red('\nFailed to save configuration'));
            console.log(chalk_1.default.gray(`Error: ${error instanceof Error ? error.message : String(error)}\n`));
            this.exit(1);
        }
    }
    setPreference(storage, key, value) {
        const validationError = preferences_resolver_1.PreferencesResolver.validate(key, value);
        if (validationError) {
            console.log(chalk_1.default.red(`\nInvalid value for '${key}': ${validationError}\n`));
            this.exit(1);
        }
        storage.setPreference(key, value);
        console.log(chalk_1.default.green(`\nPreference saved: ${key} = ${value}`));
        console.log(chalk_1.default.gray(`Location: ${storage.getConfigPath()}`));
        console.log(chalk_1.default.gray(`Description: ${preferences_schema_1.PREFERENCES[key].description}\n`));
    }
    async setProvider(storage, provider, value) {
        const schema = (0, provider_credential_schemas_1.getCredentialSchema)(provider);
        if ((0, provider_credential_schemas_1.isCompoundProvider)(provider)) {
            if (value) {
                console.log(chalk_1.default.red(`\n'${provider}' requires an Access Key + Secret Key pair — pass no value and enter them interactively.\n`));
                this.exit(1);
            }
            await this.setCompoundProvider(storage, provider, schema);
            return;
        }
        if (!value) {
            console.log(chalk_1.default.red(`\nMissing token for provider '${provider}'\n`));
            this.exit(1);
        }
        storage.saveToken(provider, value);
        console.log(chalk_1.default.green(`\nProvider configured: ${provider}`));
        console.log(chalk_1.default.gray(`Location: ${storage.getConfigPath()}`));
        console.log(chalk_1.default.gray('Encryption: AES-256-GCM\n'));
        console.log(chalk_1.default.gray(`Next: flui env create\n`));
    }
    async setCompoundProvider(storage, provider, schema) {
        console.log(chalk_1.default.dim(`\nEnter ${provider} credentials. Values are stored AES-256-GCM encrypted.\n`));
        const collected = {};
        for (const field of schema.fields) {
            const hintLabel = field.hint ? chalk_1.default.dim(` (${field.hint})`) : '';
            const value = field.secret
                ? await (0, prompts_1.promptMaskedInput)(`  ${field.label}`)
                : (await (0, prompts_1.promptInput)({
                    message: `  ${field.label}${hintLabel}`,
                })).trim();
            if (!value.trim()) {
                console.log(chalk_1.default.red(`\n${field.label} is required.\n`));
                this.exit(1);
            }
            collected[field.key] = value.trim();
        }
        if (provider === 'scaleway') {
            process.stdout.write(chalk_1.default.dim('\nValidating credentials...'));
            const result = await (0, scaleway_validator_1.validateScalewayCredentials)(collected.accessKey, collected.secretKey);
            process.stdout.write('\r\u001B[2K');
            if (!result.success) {
                console.log(chalk_1.default.red(`✖ ${result.message}\n`));
                this.exit(1);
            }
            console.log(chalk_1.default.green(`✔ ${result.message}`));
        }
        storage.saveCredentials(provider, collected);
        console.log(chalk_1.default.green(`\nProvider configured: ${provider}`));
        console.log(chalk_1.default.gray(`Location: ${storage.getConfigPath()}`));
        console.log(chalk_1.default.gray('Encryption: AES-256-GCM\n'));
        console.log(chalk_1.default.gray(`Next: flui env create\n`));
    }
    setSystem(storage, key, value) {
        if (key === 'api-url') {
            try {
                new URL(value);
            }
            catch {
                console.log(chalk_1.default.red(`\nInvalid URL: ${value}\n`));
                this.exit(1);
            }
            storage.saveApiUrl(value);
            console.log(chalk_1.default.green(`\nAPI URL saved: ${value}`));
            console.log(chalk_1.default.gray(`Location: ${storage.getConfigPath()}\n`));
            return;
        }
        this.failUnknown(key);
    }
    failUnknown(key) {
        console.log(chalk_1.default.red(`\nUnknown configuration key: '${key}'\n`));
        console.log((0, key_router_1.formatKnownKeys)());
        console.log();
        this.exit(1);
    }
}
ConfigSet.description = 'Set a configuration value. The key determines whether it is stored as a non-secret preference (e.g. email, certificateMode) or as an encrypted provider token (e.g. hetzner).';
ConfigSet.examples = [
    '<%= config.bin %> <%= command.id %> hetzner YOUR_API_TOKEN',
    '<%= config.bin %> <%= command.id %> email you@example.com',
    '<%= config.bin %> <%= command.id %> certificateMode preflight',
];
ConfigSet.args = {
    key: core_1.Args.string({
        required: true,
        description: 'Configuration key (preference name or provider name)',
    }),
    value: core_1.Args.string({
        required: false,
        description: 'Value to store. Omit for compound providers (e.g. scaleway) to enter values interactively.',
    }),
};
exports.default = ConfigSet;
