"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.appendCreateNonTemporaryTables = exports.PreviewVisitor = void 0;
const format_visitor_1 = require("./format.visitor");
class PreviewVisitor extends format_visitor_1.FormatVisitor {
    constructor(tokens, context) {
        super(tokens, { tabSize: 4, insertSpaces: true });
        this.context = context;
    }
    // preview does not support hints
    visitHints() {
        return '';
    }
    // preview does not support partitioned by
    visitPartitionedBy() {
        return '';
    }
    visitCreateTable(ctx) {
        if (ctx.TEMPORARY()) {
            const tableName = ctx.table().text;
            const source = this.compareTableName(tableName, this.context.sources);
            let withClause;
            if (source?.uri !== undefined) {
                withClause = `WITH (
  'connector' = 'filesystem',
  'path' = '${source.uri}',
  'format' = 'csv'
)`;
                return this.handleCreateTemporaryTable(ctx, withClause);
            }
            else if (this.compareTableName(tableName, this.context.sinks)) {
                withClause = `WITH ( 'connector' = 'preview' )`;
                return this.handleCreateTemporaryTable(ctx, withClause);
            }
        }
        return super.visitChildren(ctx);
    }
    handleCreateTemporaryTable(ctx, withClause) {
        const script = super.visitChildren(ctx);
        if (ctx.withValues()) {
            script.replace(super.visit(ctx.withValues()), withClause);
        }
        if (ctx.likeTable()) {
            const likeTableName = ctx.likeTable().table().text;
            const likeClause = `LIKE ${likeTableName} (
  INCLUDING ALL
  EXCLUDING PARTITIONS
  EXCLUDING OPTIONS
)`;
            return script.replace(super.visit(ctx.likeTable()), likeClause);
        }
        return script;
    }
    compareTableName(name, contexts) {
        const unquotes = name.replace(/[`"']/g, '');
        return contexts.find(s => unquotes === `${s.catalogName}.${s.databaseName}.${s.tableName}` || unquotes === s.tableName);
    }
}
exports.PreviewVisitor = PreviewVisitor;
/**
 * For every non-temporary table, we need to create a temporary table LIKE it, so we can preview them.
 *
 * @param origin original preview script
 * @param context preview context, including source and sink tables
 */
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;
//# sourceMappingURL=preview.visitor.js.map