import { ExploreCompiler } from '../compiler/exploreCompiler';
import { SupportedDbtAdapter } from '../types/dbt';
import { ExploreType } from '../types/explore';
import { DimensionType, FieldType, friendlyName, } from '../types/field';
import { WarehouseTypes } from '../types/projects';
import { WeekDay } from './timeFrames';
import { defaultNullSafeEqualSql } from './warehouse';
export const createVirtualView = (virtualViewName, sql, columns, warehouseClient, label, parameterValues) => {
    const exploreCompiler = new ExploreCompiler(warehouseClient);
    const fieldQuoteChar = warehouseClient.getFieldQuoteChar();
    const dimensions = columns.reduce((acc, column) => {
        acc[column.reference] = {
            name: column.reference,
            label: friendlyName(column.reference),
            type: column.type ?? DimensionType.STRING,
            table: virtualViewName,
            fieldType: FieldType.DIMENSION,
            sql: `${fieldQuoteChar}${column.reference}${fieldQuoteChar}`,
            tableLabel: friendlyName(virtualViewName),
            hidden: false,
        };
        return acc;
    }, {});
    const compiledTable = {
        name: virtualViewName,
        label: label || friendlyName(virtualViewName),
        sqlTable: `(${sql})`, // Wrap the sql in a subquery to avoid issues with reserved words
        dimensions,
        metrics: {},
        lineageGraph: { nodes: [], edges: [] },
        database: warehouseClient.credentials.type,
        schema: '', // TODO: what should this be?
    };
    const explore = exploreCompiler.compileExplore({
        name: virtualViewName,
        label: label || friendlyName(virtualViewName),
        tags: [],
        baseTable: virtualViewName,
        joinedTables: [],
        tables: { [virtualViewName]: compiledTable },
        targetDatabase: warehouseClient.getAdapterType(),
        meta: {},
    });
    const hasSavedParameters = parameterValues && Object.keys(parameterValues).length > 0;
    const virtualView = {
        ...explore,
        type: ExploreType.VIRTUAL,
        ...(hasSavedParameters
            ? { savedParameterValues: parameterValues }
            : {}),
    };
    return virtualView;
};
export const createTemporaryVirtualView = (virtualViewName, sql, columns) => {
    // Create a fake warehouseClient for compilation purposes
    const fakeWarehouseClient = {
        credentials: {
            type: WarehouseTypes.BIGQUERY,
            project: '',
            dataset: '',
            timeoutSeconds: 0,
            priority: 'interactive',
            keyfileContents: {},
            retries: 3,
            location: '',
            maximumBytesBilled: 0,
        },
        getCatalog: async () => ({}),
        streamQuery: async () => { },
        executeAsyncQuery: async () => ({
            queryId: null,
            queryMetadata: null,
            totalRows: 0,
            durationMs: 0,
            phaseTimings: {},
        }),
        runQuery: async () => ({ fields: {}, rows: [] }),
        test: async () => { },
        getStartOfWeek: () => WeekDay.MONDAY,
        getAdapterType: () => SupportedDbtAdapter.BIGQUERY,
        supportsCteMaterialization: () => true,
        getStringQuoteChar: () => "'",
        getEscapeStringQuoteChar: () => "''",
        getFieldQuoteChar: () => '"',
        getFloatingType: () => 'FLOAT',
        getNullSafeEqualSql: defaultNullSafeEqualSql,
        getNullSafeEqualJoinSql: defaultNullSafeEqualSql,
        getMetricSql: () => '',
        concatString: (...args) => args.join(''),
        getAllTables: async () => [],
        getFields: async () => ({}),
        parseWarehouseCatalog: () => ({}),
        parseError: (error) => error,
        escapeString: (value) => value,
        castToTimestamp: (date) => `CAST('${date.toISOString()}' AS TIMESTAMP)`,
        getIntervalSql: (value, unit) => `INTERVAL '${value} ${unit}'`,
        getTimestampDiffSeconds: (startTimestampSql, endTimestampSql) => `EXTRACT(EPOCH FROM (${endTimestampSql} - ${startTimestampSql}))`,
        getMedianSql: (valueSql) => `PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ${valueSql})`,
        buildArray: (elements) => `ARRAY[${elements.join(', ')}]`,
        buildArrayAgg: (expression, orderBy) => orderBy
            ? `ARRAY_AGG(${expression} ORDER BY ${orderBy})`
            : `ARRAY_AGG(${expression})`,
    };
    return createVirtualView(virtualViewName, sql, columns, fakeWarehouseClient);
};
//# sourceMappingURL=virtualView.js.map