import 'dotenv/config';
import { Command, Flags } from '@oclif/core';
import { loadConfig } from '../../deploy/domain/config.js';
import { loadCredentials } from '../../deploy/domain/credentials.js';
import { buildPlans, resolveEnvironments, } from '../../deploy/domain/plan-builder.js';
import { resolvePlanFiles } from '../../deploy/domain/plan-resolver.js';
import { createAdapters } from '../../deploy/factories/adapter.factory.js';
import { DeployService } from '../../deploy/services/deploy.service.js';
export default class Provision extends Command {
    static description = 'Provision Aurora project infrastructure (DNS + Hosting + CI/CD secrets).';
    static examples = [
        '<%= config.bin %> provision --ftp-password s3cret',
        '<%= config.bin %> provision --env dev --target back',
        '<%= config.bin %> provision --skip-dns --skip-cicd',
        'FTP_PASSWORD=x aurora provision          # global password for all envs',
        'DEV_FTP_PASSWORD=x PROD_FTP_PASSWORD=y aurora provision  # per-env passwords',
    ];
    static flags = {
        config: Flags.string({
            char: 'c',
            default: './aurora.yaml',
            description: 'Path to aurora.yaml config file',
        }),
        'db-password': Flags.string({
            description: 'Global DB password (fallback). Per-env: DEV_DB_PASSWORD, PROD_DB_PASSWORD, etc.',
            env: 'DB_PASSWORD',
        }),
        env: Flags.string({
            description: 'Provision only this environment (e.g. dev, qa, prod)',
        }),
        'ftp-password': Flags.string({
            description: 'Global FTP password (fallback). Per-env: DEV_FTP_PASSWORD, PROD_FTP_PASSWORD, etc.',
            env: 'FTP_PASSWORD',
        }),
        'plesk-ssh-user': Flags.string({
            default: 'root',
            description: 'SSH user for Plesk server commands',
            env: 'PLESK_SSH_USER',
        }),
        'skip-cicd': Flags.boolean({
            default: false,
            description: 'Skip CI/CD secrets/variables setup',
        }),
        'skip-dns': Flags.boolean({
            default: false,
            description: 'Skip DNS record creation',
        }),
        'skip-hosting': Flags.boolean({
            default: false,
            description: 'Skip Plesk hosting setup',
        }),
        'skip-ssh': Flags.boolean({
            default: false,
            description: 'Skip SSH key generation and installation',
        }),
        target: Flags.string({
            description: 'Provision only this target (back or front)',
            options: ['back', 'front'],
        }),
    };
    async run() {
        const { flags } = await this.parse(Provision);
        const config = loadConfig(flags.config);
        const environments = resolveEnvironments(config, flags.env);
        const envFtpPasswords = scanEnvPasswords(environments, 'FTP_PASSWORD');
        const envDbPasswords = scanEnvPasswords(environments, 'DB_PASSWORD');
        const plans = buildPlans(config, environments, {
            dbPassword: flags['db-password'],
            envDbPasswords,
            envFtpPasswords,
            ftpPassword: flags['ftp-password'],
            pleskSshUser: flags['plesk-ssh-user'],
            skipCicd: flags['skip-cicd'],
            skipDns: flags['skip-dns'],
            skipHosting: flags['skip-hosting'],
            skipSsh: flags['skip-ssh'],
        }, flags.target);
        if (plans.length === 0) {
            this.error('No deployment plans generated. Check your config and flags.');
        }
        const credentials = loadCredentials({
            skipDns: flags['skip-dns'],
            skipHosting: flags['skip-hosting'],
        });
        const adapters = createAdapters(credentials);
        const service = new DeployService(adapters);
        if (!flags['skip-cicd']) {
            await adapters.cicd.verifyAuth();
        }
        for (const plan of plans) {
            const { keysGenerated, warnings } = resolvePlanFiles(plan);
            if (keysGenerated) {
                this.log(`OAuth keys generated in ${plan.dir}/`);
            }
            for (const w of warnings) {
                this.warn(w);
            }
            try {
                await service.execute(plan); // eslint-disable-line no-await-in-loop
            }
            catch (error) {
                const label = `[${plan.environment}/${plan.target}]`;
                adapters.logger.logError(`Deploy failed ${label} — ${plan.domain}`, error);
                this.error(`Error en el despliegue ${label} de ${plan.domain}. Revisa ${adapters.logger.logFilePath} para más detalles.`);
            }
        }
    }
}
function scanEnvPasswords(environments, suffix) {
    const result = {};
    for (const env of environments) {
        const key = `${env.toUpperCase()}_${suffix}`;
        const value = process.env[key];
        if (value) {
            result[env] = value;
        }
    }
    return result;
}
