"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClickHouseHelper = void 0;
const date_fns_1 = require("date-fns");
const decimal_js_1 = __importDefault(require("decimal.js"));
const SpanAttributesGenAIPrefix = "gen_ai";
const SpanAttributesDBPrefix = "db";
const ClickHouseHelper = {
    TraceMapping: {
        // Root Key
        time: {
            label: "Time",
            type: "date",
            path: "Timestamp",
            isRoot: true,
        },
        requestDuration: {
            label: "Request Duration",
            type: "float",
            path: "Duration",
            isRoot: true,
            offset: 10e-10,
            valueSuffix: "s",
        },
        id: {
            label: "Id",
            type: "string",
            path: "TraceId",
            isRoot: true,
        },
        parentSpanId: {
            label: "Parent Span Id",
            type: "string",
            path: "ParentSpanId",
            isRoot: true,
        },
        statusCode: {
            label: "Status Code",
            type: "string",
            path: "StatusCode",
            isRoot: true,
        },
        applicationName: {
            label: "App Name",
            type: "string",
            path: "service.name",
            isRoot: true,
        },
        environment: {
            label: "Environment",
            type: "string",
            path: "deployment.environment",
            icon: "Container",
            isRoot: true,
        },
        // Exception
        serviceName: {
            label: "Service Name",
            type: "string",
            path: "ServiceName",
            isRoot: true,
            icon: "FileCog",
        },
        statusMessage: {
            label: "Error Message",
            type: "string",
            path: "StatusMessage",
            isRoot: true,
        },
        spanId: {
            label: "Span Id",
            type: "string",
            path: "SpanId",
            isRoot: true,
        },
        spanName: {
            label: "Span Name",
            type: "string",
            path: "SpanName",
            isRoot: true,
        },
        exceptionType: {
            label: "Exception type",
            type: "string",
            path: ["Events.Attributes", "0", "exception.type"],
            icon: "MessageSquareWarning",
            isRoot: true,
        },
        deploymentType: {
            label: "Deployment type",
            type: "string",
            path: ["ResourceAttributes", "deployment.environment"],
            icon: "Container",
            isRoot: true,
        },
        provider: {
            label: "Provider",
            type: "string",
            path: "system",
            prefix: SpanAttributesGenAIPrefix,
            icon: "PyramidIcon",
        },
        type: {
            label: "Type",
            type: "string",
            path: "operation.name",
            prefix: SpanAttributesGenAIPrefix,
            icon: "ClipboardType",
        },
        endpoint: {
            label: "Endpoint",
            type: "string",
            path: "endpoint",
            prefix: SpanAttributesGenAIPrefix,
            icon: "DoorClosed",
        },
        temperature: {
            label: "Temperature",
            type: "float",
            path: "temperature",
            prefix: SpanAttributesGenAIPrefix,
        },
        // Tokens & Cost
        cost: {
            label: "Usage Cost",
            type: "round",
            path: "usage.cost",
            prefix: SpanAttributesGenAIPrefix,
            icon: "CircleDollarSign",
            offset: 10,
            defaultValue: "-",
            valuePrefix: "$",
        },
        promptTokens: {
            label: "Prompt Tokens",
            type: "integer",
            path: "usage.input_tokens",
            prefix: SpanAttributesGenAIPrefix,
            icon: "Braces",
            defaultValue: "-",
        },
        completionTokens: {
            label: "Completion Tokens",
            type: "integer",
            path: "usage.output_tokens",
            prefix: SpanAttributesGenAIPrefix,
            defaultValue: "-",
        },
        totalTokens: {
            label: "Total Tokens",
            type: "integer",
            path: "usage.total_tokens",
            prefix: SpanAttributesGenAIPrefix,
            icon: "TicketPlus",
            defaultValue: "-",
        },
        maxTokens: {
            label: "Maximum tokens",
            type: "integer",
            path: "request.max_tokens",
            prefix: SpanAttributesGenAIPrefix,
            icon: "TicketCheck",
            defaultValue: "-",
        },
        // Audio
        audioVoice: {
            label: "Audio Voice",
            type: "string",
            path: "request.audio_voice",
            prefix: SpanAttributesGenAIPrefix,
            icon: "AudioLines",
        },
        audioFormat: {
            label: "Audio Format",
            type: "string",
            path: "request.audio_response_format",
            prefix: SpanAttributesGenAIPrefix,
            icon: "FileAudio2",
        },
        audioSpeed: {
            label: "Audio Speed",
            type: "string",
            path: "request.audio_speed",
            prefix: SpanAttributesGenAIPrefix,
            icon: "CircleGauge",
        },
        // Image
        image: {
            label: "Image",
            type: "string",
            path: "response.image.0",
            prefix: SpanAttributesGenAIPrefix,
        },
        imageSize: {
            label: "Image Size",
            type: "string",
            path: "request.image_size",
            prefix: SpanAttributesGenAIPrefix,
            icon: "ImageIcon",
        },
        imageQuality: {
            label: "Image Quality",
            type: "string",
            path: "request.image_quality",
            prefix: SpanAttributesGenAIPrefix,
            icon: "ScanSearch",
        },
        imageStyle: {
            label: "Image Style",
            type: "string",
            path: "request.image_style",
            prefix: SpanAttributesGenAIPrefix,
            icon: "Crop",
        },
        // Request and Response
        model: {
            label: "Model",
            type: "string",
            path: "request.model",
            prefix: SpanAttributesGenAIPrefix,
            icon: "Boxes",
        },
        prompt: {
            label: "Prompt",
            type: "string",
            path: ["Events.Attributes", "0", "gen_ai.prompt"],
            isRoot: true,
        },
        finishReason: {
            label: "Finish Reason",
            type: "string",
            path: "response.finish_reasons",
            prefix: SpanAttributesGenAIPrefix,
        },
        response: {
            label: "Response",
            type: "string",
            path: ["Events.Attributes", "1", "gen_ai.completion"],
            isRoot: true,
        },
        randomSeed: {
            label: "Random seed",
            type: "float",
            path: "request.seed",
            prefix: SpanAttributesGenAIPrefix,
        },
        revisedPrompt: {
            label: "Revised Prompt",
            type: "string",
            path: ["SpanAttributes", "gen_ai.content.revised_prompt"],
            isRoot: true,
        },
        // Embedding
        embeddingFormat: {
            label: "Embedding Format",
            type: "string",
            path: "request.embedding_format",
            prefix: SpanAttributesGenAIPrefix,
        },
        embeddingDimension: {
            label: "Embedding Dimension",
            type: "string",
            path: "request.embedding_dimension",
            prefix: SpanAttributesGenAIPrefix,
        },
        // Fine tune
        trainingFile: {
            label: "Training File",
            type: "string",
            path: "request.training_file",
            prefix: SpanAttributesGenAIPrefix,
        },
        validationFile: {
            label: "Validation File",
            type: "string",
            path: "request.validation_file",
            prefix: SpanAttributesGenAIPrefix,
        },
        fineTuneBatchSize: {
            label: "Fine Tune Batch Size",
            type: "string",
            path: "request.fine_tune_batch_size",
            prefix: SpanAttributesGenAIPrefix,
        },
        learningRateMultiplier: {
            label: "Learning rate multiplier",
            type: "string",
            path: "request.learning_rate_multiplier",
            prefix: SpanAttributesGenAIPrefix,
        },
        fineTuneNEpochs: {
            label: "Fine Tune and Epochs",
            type: "string",
            path: "request.fine_tune_n_epochs",
            prefix: SpanAttributesGenAIPrefix,
        },
        fineTuneModelSuffix: {
            label: "Fine Tune Model Suffix",
            type: "string",
            path: "request.fine_tune_model_suffix",
            prefix: SpanAttributesGenAIPrefix,
        },
        finetuneJobStatus: {
            label: "Fine Tune Job Status",
            type: "string",
            path: "request.fine_tune_status",
            prefix: SpanAttributesGenAIPrefix,
        },
        // vector db
        operation: {
            label: "Operation",
            type: "string",
            path: "operation",
            prefix: SpanAttributesDBPrefix,
            icon: "SquareRadical",
        },
        system: {
            label: "Provider",
            type: "string",
            path: "system",
            prefix: SpanAttributesDBPrefix,
            icon: "PyramidIcon",
        },
        documentsCount: {
            label: "Documents count",
            type: "integer",
            path: "documents_count",
            prefix: SpanAttributesDBPrefix,
            icon: "FileStack",
        },
        idsCount: {
            label: "Ids count",
            type: "integer",
            path: "ids_count",
            prefix: SpanAttributesDBPrefix,
            icon: "Fingerprint",
        },
        vectorCount: {
            label: "Vector count",
            type: "integer",
            path: "vector_count",
            prefix: SpanAttributesDBPrefix,
            icon: "Factory",
        },
        statement: {
            label: "Statement",
            type: "string",
            path: "statement",
            prefix: SpanAttributesDBPrefix,
        },
        nResults: {
            label: "N results",
            type: "string",
            path: "n_results",
            prefix: SpanAttributesDBPrefix,
        },
        collectionName: {
            label: "Collection Name",
            type: "string",
            path: "collection.name",
            prefix: SpanAttributesDBPrefix,
            icon: "Combine",
        },
        whereDocument: {
            label: "Where Document",
            type: "string",
            path: "where_document",
            prefix: SpanAttributesDBPrefix,
        },
        filter: {
            label: "Filter",
            type: "string",
            path: "filter",
            prefix: SpanAttributesDBPrefix,
        },
        // framework
        owner: {
            label: "Hub Owner",
            type: "string",
            path: "hub.owner",
            prefix: SpanAttributesGenAIPrefix,
            icon: "ShieldCheck",
        },
        repo: {
            label: "Hub Repo",
            type: "string",
            path: "hub.repo",
            prefix: SpanAttributesGenAIPrefix,
            icon: "BookKey",
        },
        retrievalSource: {
            label: "Retrieval Source",
            type: "string",
            path: "retrieval.source",
            prefix: SpanAttributesGenAIPrefix,
            icon: "SquareCode",
        },
        // average input and output tokens
        averageInputTokens: {
            label: "Average Input Tokens",
            type: "integer",
            path: "usage.input_tokens",
            prefix: SpanAttributesGenAIPrefix,
        },
        averageOutputTokens: {
            label: "Average Output Tokens",
            type: "integer",
            path: "usage.output_tokens",
            prefix: SpanAttributesGenAIPrefix,
        },
    },
    /**
     * Get the full path of a trace mapping key
     * @param key - The key to get the full path of
     * @param shouldReturnArray - Whether to return an array of the full path
     * @returns The full path of the trace mapping key
     */
    getTraceMappingKeyFullPath: (key, shouldReturnArray = false) => {
        if (!ClickHouseHelper.TraceMapping[key].prefix) {
            if (!shouldReturnArray) {
                // eslint-disable-next-line unicorn/no-lonely-if
                if (typeof ClickHouseHelper.TraceMapping[key].path !== "string") {
                    return ClickHouseHelper.TraceMapping[key].path.join(".");
                }
            }
            return ClickHouseHelper.TraceMapping[key].path;
        }
        if (shouldReturnArray) {
            let returnArr = [];
            if (typeof ClickHouseHelper.TraceMapping[key].prefix === "string") {
                returnArr = returnArr.concat([ClickHouseHelper.TraceMapping[key].prefix]);
            }
            else {
                returnArr = returnArr.concat(ClickHouseHelper.TraceMapping[key].prefix);
            }
            if (typeof ClickHouseHelper.TraceMapping[key].path === "string") {
                returnArr = returnArr.concat([ClickHouseHelper.TraceMapping[key].path]);
            }
            else {
                returnArr = returnArr.concat(ClickHouseHelper.TraceMapping[key].path);
            }
            return returnArr;
        }
        let returnString = "";
        if (typeof ClickHouseHelper.TraceMapping[key].prefix === "string") {
            returnString = ClickHouseHelper.TraceMapping[key].prefix;
        }
        else {
            returnString = ClickHouseHelper.TraceMapping[key].prefix.join(".");
        }
        if (typeof ClickHouseHelper.TraceMapping[key].path === "string") {
            returnString = [returnString, ClickHouseHelper.TraceMapping[key].path].join(".");
        }
        else {
            returnString = [
                returnString,
                ClickHouseHelper.TraceMapping[key].path.join("."),
            ].join(".");
        }
        return returnString;
    },
    /**
     * Get the where condition for a filter
     * @param filter - The filter to get the where condition for
     * @param filterSelectedConfig - Whether to filter by the selected config
     * @returns The where condition for the filter
     */
    getFilterWhereCondition: (filter, filterSelectedConfig) => {
        const whereArray = [];
        try {
            const { start, end } = filter.timeLimit || {};
            if (start && end) {
                whereArray.push(`Timestamp >= parseDateTimeBestEffort('${start}') AND Timestamp <= parseDateTimeBestEffort('${end}')`);
            }
            if (filterSelectedConfig && filter.selectedConfig) {
                if (filter.selectedConfig.models?.length) {
                    whereArray.push(`SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("model")}'] IN (${filter.selectedConfig.models
                        .map((model) => `'${model}'`)
                        .join(", ")})`);
                }
                if (filter.selectedConfig.providers?.length) {
                    whereArray.push(`(SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("system")}'] IN (${filter.selectedConfig.providers
                        .map((provider) => `'${provider}'`)
                        .join(", ")}) OR SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("provider")}'] IN (${filter.selectedConfig.providers
                        .map((provider) => `'${provider}'`)
                        .join(", ")}))`);
                }
                if (filter.selectedConfig.traceTypes?.length) {
                    whereArray.push(`SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("type")}'] IN (${filter.selectedConfig.traceTypes
                        .map((type) => `'${type}'`)
                        .join(", ")})`);
                }
                if (filter.selectedConfig.maxCost) {
                    whereArray.push(`toFloat64OrZero(SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("cost")}']) BETWEEN 0 AND ${filter.selectedConfig.maxCost.toFixed(10)}`);
                }
                if (filter.selectedConfig.applicationNames?.length) {
                    whereArray.push(`ResourceAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("applicationName")}'] IN (${filter.selectedConfig.applicationNames
                        .map((applicationName) => `'${applicationName}'`)
                        .join(", ")})`);
                }
                if (filter.selectedConfig.environments?.length) {
                    whereArray.push(`ResourceAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("environment")}'] IN (${filter.selectedConfig.environments
                        .map((environment) => `'${environment}'`)
                        .join(", ")})`);
                }
            }
            if (filter.notOrEmpty && filter.notOrEmpty?.length > 0) {
                const whereOrArray = [];
                filter.notOrEmpty.map(({ key }) => {
                    whereOrArray.push(`notEmpty(${key})`);
                });
                whereArray.push(`( ${whereOrArray.join(" OR ")} )`);
            }
            if (filter.notEmpty && filter.notEmpty?.length > 0) {
                filter.notEmpty.map(({ key }) => {
                    whereArray.push(`notEmpty(${key})`);
                });
            }
            // const {
            //   statusCode = ["STATUS_CODE_OK", "STATUS_CODE_UNSET", "Ok", "Unset"],
            // } = filter;
            // if (statusCode?.length > 0) {
            //   whereArray.push(
            //     `StatusCode IN (${statusCode.map((type) => `'${type}'`).join(", ")})`
            //   );
            // }
            if (filter.operationType) {
                if (filter.operationType === "vectordb") {
                    whereArray.push(`SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("type")}'] = 'vectordb'`);
                }
                else {
                    whereArray.push(`SpanAttributes['${ClickHouseHelper.getTraceMappingKeyFullPath("type")}'] != 'vectordb'`);
                }
            }
        }
        catch { }
        return whereArray.join(" AND ");
    },
    /**
     * Get the previous params for a filter
     * @param filter - The filter to get the previous params for
     * @returns The previous params for the filter
     */
    getFilterPreviousParams: (filter) => {
        try {
            const previousParams = JSON.parse(JSON.stringify(filter));
            const { start, end, type } = filter.timeLimit || {};
            switch (type) {
                case "24H":
                    previousParams.timeLimit.start = (0, date_fns_1.addDays)(start, -1).toISOString();
                    previousParams.timeLimit.end = (0, date_fns_1.addDays)(end, -1).toISOString();
                    break;
                case "7D":
                    previousParams.timeLimit.start = (0, date_fns_1.addDays)(start, -7).toISOString();
                    previousParams.timeLimit.end = (0, date_fns_1.addDays)(end, -1).toISOString();
                    break;
                case "1M":
                    previousParams.timeLimit.start = (0, date_fns_1.addMonths)(start, -1).toISOString();
                    previousParams.timeLimit.end = (0, date_fns_1.addMonths)(end, -1).toISOString();
                    break;
                case "3M":
                    previousParams.timeLimit.start = (0, date_fns_1.addMonths)(start, -3).toISOString();
                    previousParams.timeLimit.end = (0, date_fns_1.addMonths)(end, -3).toISOString();
                    break;
                case "CUSTOM":
                    const differenceDays = (0, date_fns_1.differenceInDays)(end, start);
                    previousParams.timeLimit.start = (0, date_fns_1.addDays)(start, -differenceDays).toISOString();
                    previousParams.timeLimit.end = (0, date_fns_1.addDays)(end, -differenceDays).toISOString();
                    break;
                default:
            }
            return previousParams;
        }
        catch {
            return filter;
        }
    },
    /**
     * Get the date truncation grouping logic
     * @param end - The end date
     * @param start - The start date
     * @returns The date truncation grouping logic
     */
    dateTruncGroupingLogic: (end, start, type) => {
        let dateTrunc = "day";
        if ((0, date_fns_1.differenceInYears)(end, start) >= 1) {
            dateTrunc = "month";
        }
        else if ((0, date_fns_1.differenceInDays)(end, start) <= 1) {
            dateTrunc = "hour";
        }
        if (type === 'today' || type === 'yesterday' || type === '24H') {
            dateTrunc = "hour";
        }
        return dateTrunc;
    },
    safeConvertToNumber: (value) => {
        if (typeof value === "number") {
            return value;
        }
        if (value === null) {
            return 1;
        }
        const number = Number.parseFloat(value);
        if (Number.isNaN(number)) {
            return 1;
        }
        return number;
    },
    processTotalRecordsGraph: (data) => {
        const processedData = (data ?? [])?.flat().map((item) => {
            return {
                x: item?.[0],
                y: ClickHouseHelper.safeConvertToNumber(item?.[1]),
                series: item?.[2],
                xEnd: typeof item?.[3] === 'string' ? item[3] : undefined,
            };
        });
        // Filter out entries with zero or null values to avoid empty bars
        // return processedData.filter((item: any) => item.y > 0);
        return processedData;
    },
    processMetricFailureAnalysis: (data, types = [], postFix = '') => {
        const processedData = (data ?? []).map((item) => {
            return {
                name: item?.type,
                value: types?.map((type) => new decimal_js_1.default(item?.[type] ?? 0).toNumber()).reduce((a, b) => a + b, 0),
                postFix,
            };
        });
        return processedData;
    },
};
exports.ClickHouseHelper = ClickHouseHelper;
//# sourceMappingURL=index.js.map