"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.MigrationCreateCommand = void 0;
const tslib_1 = require("tslib");
function __assignType(fn, args) {
    fn.__type = args;
    return fn;
}
/*@ts-ignore*/
var { __ΩFlag } = require('@deepkit/app');
const app_1 = require("@deepkit/app");
const state_1 = require("../../../app/state");
const resolver_1 = require("../../../app/resolver");
const services_1 = require("../../../services");
const dialect_1 = require("../../dialect");
const entity_reader_1 = require("./entity-reader");
const db_reader_1 = require("./db-reader");
const comparator_1 = require("./comparator");
const ddl_generator_1 = require("./ddl-generator");
const file_generator_1 = require("./file-generator");
const prompt_1 = require("./prompt");
const schema_model_1 = require("./schema-model");
let MigrationCreateCommand = class MigrationCreateCommand {
    constructor(dbProvider) {
        this.dbProvider = dbProvider;
        this.logger = (0, services_1.createLogger)('MigrationCreate');
    }
    async execute(nonInteractive = false) {
        if (nonInteractive) {
            (0, prompt_1.setNonInteractive)(true);
        }
        try {
            const db = this.dbProvider.db;
            const dialect = (0, dialect_1.getDialect)(db.adapter);
            const pgSchema = dialect === 'postgres' ? ((0, resolver_1.getAppConfig)().PG_SCHEMA ?? 'public') : 'public';
            this.logger.info(`Dialect: ${dialect}`);
            // Step 1: Read entity schema
            this.logger.info('Reading entity definitions...');
            const entitySchema = (0, entity_reader_1.readEntitiesSchema)(db, dialect);
            const entityTableNames = Array.from(entitySchema.keys());
            this.logger.info(`Found ${entityTableNames.length} entity table(s): ${entityTableNames.join(', ')}`);
            // Step 2: Discover all DB tables and union with entity table names
            const allDbTableNames = await (0, db_reader_1.readAllTableNames)(db, dialect, pgSchema);
            const dbOnlyTables = allDbTableNames.filter(__assignType(n => !entitySchema.has(n) && !schema_model_1.INTERNAL_TABLES.has(n), ['n', '', 'P"2!"/"']));
            const tableNames = [...entityTableNames, ...dbOnlyTables];
            // Step 3: Read database schema
            this.logger.info('Reading database schema...');
            const dbSchema = await (0, db_reader_1.readDatabaseSchema)(db, dialect, tableNames, pgSchema);
            // Step 4: Compare schemas
            this.logger.info('Comparing schemas...');
            const diff = await (0, comparator_1.compareSchemas)(entitySchema, dbSchema, dialect, !nonInteractive, pgSchema);
            // Step 5: Generate DDL
            const statements = (0, ddl_generator_1.generateDDL)(diff);
            if (statements.length === 0) {
                this.logger.info('No schema changes detected.');
                return;
            }
            // Step 6: Show summary
            this.logger.info(`\nChanges detected:`);
            if (diff.addedTables.length > 0) {
                this.logger.info(`  Added tables: ${diff.addedTables.map(__assignType(t => t.name, ['t', '', 'P"2!"/"'])).join(', ')}`);
            }
            if (diff.removedTables.length > 0) {
                this.logger.info(`  Removed tables: ${diff.removedTables.map(__assignType(t => t.name, ['t', '', 'P"2!"/"'])).join(', ')}`);
            }
            for (const table of diff.modifiedTables) {
                const changes = [];
                if (table.addedColumns.length > 0)
                    changes.push(`+${table.addedColumns.length} cols`);
                if (table.removedColumns.length > 0)
                    changes.push(`-${table.removedColumns.length} cols`);
                if (table.modifiedColumns.length > 0)
                    changes.push(`~${table.modifiedColumns.length} cols`);
                if (table.renamedColumns.length > 0)
                    changes.push(`${table.renamedColumns.length} renamed`);
                if (table.addedIndexes.length > 0)
                    changes.push(`+${table.addedIndexes.length} idx`);
                if (table.removedIndexes.length > 0)
                    changes.push(`-${table.removedIndexes.length} idx`);
                if (table.primaryKeyChanged)
                    changes.push('PK changed');
                this.logger.info(`  ${table.tableName}: ${changes.join(', ')}`);
            }
            this.logger.info(`\nDDL statements (${statements.length}):`);
            for (const stmt of statements) {
                this.logger.info(`  ${stmt}`);
            }
            // Step 7: Prompt for description and generate file
            services_1.pinoLogger.flush();
            await new Promise(__assignType(resolve => setTimeout(resolve, 100), ['resolve', '', 'P"2!"/"']));
            const description = await (0, prompt_1.promptMigrationDescription)();
            const filePath = (0, file_generator_1.generateMigrationFile)(statements, description);
            this.logger.info(`\nMigration file created: ${filePath}`);
        }
        finally {
            (0, prompt_1.setNonInteractive)(false);
        }
    }
};
exports.MigrationCreateCommand = MigrationCreateCommand;
MigrationCreateCommand.__type = ['logger', function () { return (0, services_1.createLogger)('MigrationCreate'); }, () => state_1.DBProvider, 'dbProvider', 'constructor', () => __ΩFlag, "Skip interactive prompts", 'description', 'nonInteractive', () => false, 'execute', 'MigrationCreateCommand', '!3!;>"PP7#2$;"0%PP)P.\'4(Mo&"K2)>*"0+5w,'];
exports.MigrationCreateCommand = MigrationCreateCommand = tslib_1.__decorate([
    app_1.cli.controller('migration:create'),
    tslib_1.__metadata("design:paramtypes", [state_1.DBProvider])
], MigrationCreateCommand);
//# sourceMappingURL=MigrationCreateCommand.js.map