import { NotImplementedError } from '../types/errors';
import { BinType, DimensionType, friendlyName, isCustomBinDimension, } from '../types/field';
import assertUnreachable from './assertUnreachable';
import { getCustomGroupSelectSql, getCustomRangeSelectSql, getFixedWidthBinSelectSql, } from './customDimensions';
import { defaultNullSafeEqualSql } from './warehouse';
export const convertCustomSqlDimensionToDbt = (field) => ({
    label: friendlyName(field.name),
    type: field.dimensionType,
    sql: field.sql,
});
export const convertCustomBinDimensionToDbt = ({ customDimension, baseDimensionSql, warehouseSqlBuilder, }) => {
    switch (customDimension.binType) {
        case BinType.CUSTOM_RANGE:
            return {
                label: friendlyName(customDimension.name),
                type: DimensionType.STRING,
                sql: getCustomRangeSelectSql({
                    binRanges: customDimension.customRange,
                    baseDimensionSql,
                    warehouseSqlBuilder,
                }),
            };
        case BinType.FIXED_WIDTH:
            return {
                label: friendlyName(customDimension.name),
                type: DimensionType.STRING,
                sql: getFixedWidthBinSelectSql({
                    binWidth: customDimension.binWidth,
                    baseDimensionSql,
                    warehouseSqlBuilder,
                }),
            };
        case BinType.FIXED_NUMBER:
            throw new NotImplementedError('Bin with fixed number of bins can not be converted to dbt as it requires a CTE');
        case BinType.CUSTOM_GROUP:
            return {
                label: friendlyName(customDimension.name),
                type: DimensionType.STRING,
                sql: getCustomGroupSelectSql({
                    binGroups: customDimension.customGroups,
                    baseDimensionSql,
                    warehouseSqlBuilder,
                }),
            };
        default:
            throw new Error(`Unknown bin type ${assertUnreachable(customDimension, 'Unknown bin type')}`);
    }
};
// Mock Bigquery warehouse client for preview
const warehouseClientMock = {
    credentials: undefined,
    getCatalog() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    getAsyncQueryResults() {
        throw new NotImplementedError('getAsyncQueryResults not implemented');
    },
    getAdapterType() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    getAllTables() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    getFields() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    getMetricSql() {
        throw new NotImplementedError('getMetricSql not implemented');
    },
    getStartOfWeek() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    parseError() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    parseWarehouseCatalog() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    runQuery() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    streamQuery() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    executeAsyncQuery() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    test() {
        throw new NotImplementedError('getCatalog not implemented');
    },
    concatString(...args) {
        return `CONCAT(${args.join(', ')})`;
    },
    getStringQuoteChar() {
        return "'";
    },
    getEscapeStringQuoteChar() {
        return '\\';
    },
    getFieldQuoteChar() {
        return '"';
    },
    getFloatingType() {
        return 'FLOAT';
    },
    getNullSafeEqualSql: defaultNullSafeEqualSql,
    escapeString(value) {
        return value;
    },
    castToTimestamp(date) {
        return `CAST('${date.toISOString()}' AS TIMESTAMP)`;
    },
    getIntervalSql(value, unit) {
        return `INTERVAL '${value} ${unit}'`;
    },
    getTimestampDiffSeconds(startTimestampSql, endTimestampSql) {
        return `EXTRACT(EPOCH FROM (${endTimestampSql} - ${startTimestampSql}))`;
    },
    getMedianSql(valueSql) {
        return `PERCENTILE_CONT(0.5) WITHIN GROUP (ORDER BY ${valueSql})`;
    },
    buildArray(elements) {
        return `ARRAY[${elements.join(', ')}]`;
    },
    buildArrayAgg(expression, orderBy) {
        return orderBy
            ? `ARRAY_AGG(${expression} ORDER BY ${orderBy})`
            : `ARRAY_AGG(${expression})`;
    },
};
export const previewConvertCustomDimensionToDbt = (field) => {
    if (isCustomBinDimension(field)) {
        // Mock base dimension SQL and warehouse client for preview
        const preview = convertCustomBinDimensionToDbt({
            customDimension: field,
            baseDimensionSql: '${reference_column}',
            warehouseSqlBuilder: warehouseClientMock,
        });
        return {
            ...preview,
            // Add a comment at the top of the multiline string to indicate that this is a preview
            sql: `/* This is a preview! Replace column references and confirm SQL before using in production. */\n${preview.sql}`,
        };
    }
    return convertCustomSqlDimensionToDbt(field);
};
//# sourceMappingURL=convertCustomDimensionsToYaml.js.map