'use strict';

/**
 * Contract: schema generate-ddl
 *
 * Generate DDL SQL untuk seluruh model di folder schema. Run loader +
 * cross-model validation, lalu emit CREATE TABLE / CREATE INDEX (dan
 * optional DROP TABLE) dalam topological order.
 *
 * Inline migration v4.0.0: business logic dari dbschema-generate-ddl.js
 * dipindah ke handler. Hidden flag `--max-name-length` tidak di-promote ke
 * contract sesuai keputusan Phase 2 #2.
 */

const fs = require('fs');
const path = require('path');

const { loadSchemaPath } = require('../../lib/dbschema-kit/loader');
const { validateCrossModel } = require('../../lib/dbschema-kit/validator/cross-model-validator');
const { generateDDL } = require('../../lib/dbschema-kit/ddl-generator');

const SUPPORTED_DIALECTS = ['postgres', 'mysql', 'oracle', 'sqlite'];

module.exports = {
    resource: 'schema',
    verb: 'generate-ddl',
    description: 'Generate DDL SQL (CREATE TABLE, CREATE INDEX, opsional DROP) untuk seluruh schema models',
    category: 'generation',
    flags: {
        path: {
            type: 'string',
            required: true,
            description: 'Path file atau folder schema (mis. ./schema atau ./schema/users.js)'
        },
        dialect: {
            type: 'string',
            required: true,
            description: 'Target SQL dialect (postgres|mysql|oracle|sqlite)'
        },
        out: {
            type: 'string',
            required: false,
            default: null,
            description: 'File output untuk DDL hasil generate (default: stdout)'
        },
        drop: {
            type: 'boolean',
            required: false,
            default: false,
            description: 'Sertakan statement DROP TABLE sebelum CREATE'
        }
    },
    examples: [
        'npx restforge schema generate-ddl --path=./schema --dialect=postgres --out=migration.sql',
        'npx restforge schema generate-ddl --path=./schema --dialect=mysql --drop=true'
    ],
    async handler(args) {
        if (!args.dialect) {
            console.error("Error: --dialect is required (one of: postgres, mysql, oracle, sqlite)");
            throw new Error('--dialect is required');
        }

        if (!SUPPORTED_DIALECTS.includes(args.dialect)) {
            console.error(`Error: Unknown dialect '${args.dialect}'. Supported: ${SUPPORTED_DIALECTS.join(', ')}`);
            throw new Error(`Unknown dialect '${args.dialect}'`);
        }

        const schemaPath = args.path;
        const absPath = path.resolve(process.cwd(), schemaPath);

        let models;
        try {
            models = loadSchemaPath(absPath);
        } catch (err) {
            console.error(`Error: ${err.message}`);
            throw err;
        }

        const crossModelIssues = validateCrossModel(models);
        const crossModelErrors = crossModelIssues.filter((i) => i.severity === 'error');
        if (crossModelErrors.length > 0) {
            for (const issue of crossModelErrors) {
                console.error(`Error: Cross-model validation failed: ${issue.message}`);
            }
            throw new Error(`Cross-model validation failed with ${crossModelErrors.length} error(s)`);
        }

        let sql;
        try {
            const ddlOptions = { dialect: args.dialect, drop: args.drop };
            sql = generateDDL(models, ddlOptions);
        } catch (err) {
            console.error(`Error: DDL generation failed: ${err.message}`);
            throw err;
        }

        if (args.out) {
            const outPath = path.resolve(process.cwd(), args.out);
            try {
                fs.writeFileSync(outPath, sql, { encoding: 'utf-8' });
            } catch (err) {
                console.error(`Error: Failed to write output file '${outPath}': ${err.message}`);
                throw err;
            }
        } else {
            process.stdout.write(sql);
        }
    }
};
