"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendCreateNonTemporaryTables = exports.PreviewListener = void 0;
class PreviewListener {
    constructor(originalScript, context) {
        this.originalScript = originalScript;
        this.context = context;
        this.replaceItems = [];
        this.offset = 0;
    }
    get previewScript() {
        const replacements = this.replaceItems.sort((pre, next) => pre.startIndex - next.startIndex);
        let script = this.originalScript;
        replacements.forEach(r => {
            script = this.replaceSubstring(script, r.startIndex, r.stopIndex, r.replaceText);
        });
        return script;
    }
    replaceSubstring(originalText, startIndex, endIndex, replaceText) {
        const result = originalText.substring(0, Math.max(0, startIndex + this.offset)) +
            replaceText +
            originalText.substring(endIndex + this.offset);
        this.offset += replaceText.length - (endIndex - startIndex);
        return result;
    }
    compareTableName(name, contexts) {
        const unquotes = name.replace(/[`"']/g, '');
        return contexts.find(s => unquotes === `${s.catalogName}.${s.databaseName}.${s.tableName}` || unquotes === s.tableName);
    }
    handleCreateTemporaryTable(ctx, withClause) {
        if (ctx.withValues() && ctx.withValues().stop) {
            this.replaceItems.push({
                startIndex: ctx.withValues().start.startIndex,
                stopIndex: ctx.withValues().stop.stopIndex + 1,
                replaceText: withClause
            });
        }
        if (ctx.likeTable() && ctx.likeTable().stop) {
            const likeTableName = ctx.likeTable().table().text;
            const likeClause = `LIKE ${likeTableName} (
  INCLUDING ALL
  EXCLUDING PARTITIONS
  EXCLUDING OPTIONS
)`;
            this.replaceItems.push({
                startIndex: ctx.likeTable().start.startIndex,
                stopIndex: ctx.likeTable().stop.stopIndex + 1,
                replaceText: likeClause
            });
        }
    }
    enterCreateTable(ctx) {
        if (ctx.TEMPORARY()) {
            const tableName = ctx.table().text;
            const source = this.compareTableName(tableName, this.context.sources);
            if (source?.uri !== undefined) {
                this.handleCreateTemporaryTable(ctx, `WITH (
  'connector' = 'filesystem',
  'path' = '${source.uri}',
  'format' = 'csv'
)`);
            }
            else if (this.compareTableName(tableName, this.context.sinks)) {
                this.handleCreateTemporaryTable(ctx, `WITH ('connector' = 'preview')`);
            }
        }
    }
    enterPartitionedBy(ctx) {
        this.replaceItems.push({
            startIndex: ctx.start.startIndex,
            stopIndex: ctx.stop.stopIndex + 1,
            replaceText: ''
        });
    }
    enterHints(ctx) {
        this.replaceItems.push({ startIndex: ctx.start.startIndex, stopIndex: ctx.stop.stopIndex + 1, replaceText: '' });
    }
}
exports.PreviewListener = PreviewListener;
function appendCreateNonTemporaryTables(origin, context) {
    let script = '';
    context.sinks
        .filter(sink => !sink.temporary)
        .forEach(sink => {
        script += `CREATE TEMPORARY TABLE \`${sink.catalogName}\`.\`${sink.databaseName}\`.\`${sink.tableName}\`
  WITH (
    'connector' = 'preview'
  )
  LIKE \`${sink.catalogName}\`.\`${sink.databaseName}\`.\`${sink.tableName}\`(
    INCLUDING ALL
    EXCLUDING PARTITIONS
    EXCLUDING OPTIONS
  );\n\n`;
    });
    context.sources
        .filter(source => !source.temporary && source.uri)
        .forEach(source => {
        script += `CREATE TEMPORARY TABLE \`${source.catalogName}\`.\`${source.databaseName}\`.\`${source.tableName}\`
  WITH (
    'connector' = 'filesystem',
    'path' = '${source.uri}',
    'format' = 'csv'
  )
  LIKE \`${source.catalogName}\`.\`${source.databaseName}\`.\`${source.tableName}\`(
    INCLUDING ALL
    EXCLUDING PARTITIONS
    EXCLUDING OPTIONS
  );\n\n`;
    });
    script += origin;
    return script;
}
exports.appendCreateNonTemporaryTables = appendCreateNonTemporaryTables;
