"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.clickhouseSchemaService = exports.ClickHouseSchemaValidationError = void 0;
const logger_1 = __importDefault(require("../../logger"));
const clickhouseService_1 = require("./clickhouseService");
const IDENTIFIER_RE = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
class ClickHouseSchemaValidationError extends Error {
    constructor(message) {
        super(message);
        this.name = 'ClickHouseSchemaValidationError';
    }
}
exports.ClickHouseSchemaValidationError = ClickHouseSchemaValidationError;
function assertClickHouseIdentifier(name, label) {
    if (!name || !IDENTIFIER_RE.test(name)) {
        throw new ClickHouseSchemaValidationError(`Invalid ${label}: must be a single ClickHouse identifier (letters, digits, underscore; start with letter or underscore)`);
    }
}
/**
 * Table name is either `table` or `database.table` (each segment a safe identifier).
 */
function assertTableName(tableName) {
    const trimmed = tableName.trim();
    const segments = trimmed.split('.');
    if (segments.length > 2) {
        throw new ClickHouseSchemaValidationError('tableName must be `table` or `database.table`');
    }
    for (const segment of segments) {
        assertClickHouseIdentifier(segment, 'tableName');
    }
}
/**
 * Column type fragment for ADD COLUMN — not arbitrary SQL. Rejects quotes, comments, and semicolons.
 */
function assertClickHouseColumnType(columnType) {
    const t = columnType.trim();
    if (t.length < 1 || t.length > 512) {
        throw new ClickHouseSchemaValidationError('columnType must be between 1 and 512 characters');
    }
    if (/[`'";\\]|--|\/\*|\*\//.test(t)) {
        throw new ClickHouseSchemaValidationError('columnType contains forbidden characters or comment markers');
    }
    if (!/^[A-Za-z0-9_(),\s.:+|-]+$/u.test(t)) {
        throw new ClickHouseSchemaValidationError('columnType contains invalid characters');
    }
}
exports.clickhouseSchemaService = {
    /**
     * Runs `ALTER TABLE ... ADD COLUMN IF NOT EXISTS ...` on ClickHouse.
     */
    async addColumnIfNotExists(params) {
        assertTableName(params.tableName);
        assertClickHouseIdentifier(params.columnName, 'columnName');
        assertClickHouseColumnType(params.columnType);
        if (params.afterColumn !== undefined && params.afterColumn !== '') {
            assertClickHouseIdentifier(params.afterColumn, 'afterColumn');
        }
        const after = params.afterColumn !== undefined && params.afterColumn !== ''
            ? ` AFTER ${params.afterColumn}`
            : '';
        const sql = `ALTER TABLE ${params.tableName.trim()} ADD COLUMN IF NOT EXISTS ${params.columnName} ${params.columnType.trim()}${after}`;
        logger_1.default.warn(`Executing ClickHouse DDL: ${sql}`);
        await clickhouseService_1.clickHouseService.command(sql);
        return { sql };
    },
};
//# sourceMappingURL=clickhouseSchemaService.js.map