"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.validateInstanceURL = exports.buildCSVData = void 0;
const actions_core_1 = require("@segment/actions-core");
const camelCase_1 = __importDefault(require("lodash/camelCase"));
const isSettingsKey = new Set([
    'operation',
    'traits',
    'enable_batching',
    'customFields',
    'bulkUpsertExternalId',
    'bulkUpdateRecordId',
    'recordMatcherOperator',
    'customObjectName',
    'batch_size'
]);
const NO_VALUE = `#N/A`;
const validateHeaderField = (field) => {
    if (field.includes(',')) {
        throw new actions_core_1.IntegrationError(`Invalid character in field name: ${field}`, `Invalid character in field name: ${field}`, 400);
    }
};
const escapeDoubleQuotes = (value) => {
    if (typeof value !== 'string')
        return value;
    return value.replace(/"/g, '""');
};
const buildHeaderMap = (payloads) => {
    const headerMap = new Map();
    for (let i = payloads.length - 1; i >= 0; i--) {
        const payload = payloads[i];
        Object.entries(payload).forEach(([key, value]) => {
            if (!isSettingsKey.has(key)) {
                const pascalKey = snakeCaseToPascalCase(key);
                const actualValue = value;
                if (headerMap.has(pascalKey)) {
                    headerMap.get(pascalKey)?.push([actualValue, i]);
                }
                else {
                    headerMap.set(pascalKey, [[actualValue, i]]);
                }
            }
            if (key === 'customFields') {
                const customFields = value;
                Object.entries(customFields).forEach(([customFieldName, customFieldValue]) => {
                    validateHeaderField(customFieldName);
                    if (!headerMap.has(customFieldName)) {
                        headerMap.set(customFieldName, [[customFieldValue, i]]);
                    }
                    else {
                        headerMap.get(customFieldName)?.push([customFieldValue, i]);
                    }
                });
            }
        });
    }
    return headerMap;
};
const buildHeaders = (headerMap) => {
    let headers = '';
    for (const [key, _] of headerMap.entries()) {
        headers += `${key},`;
    }
    return headers;
};
const buildCSVFromHeaderMap = (payloads, headerMap, n, operation, csvStats) => {
    let rows = '';
    let totalNoValueFound = 0;
    let totalValuesInCSV = 0;
    for (let i = 0; i < n; i++) {
        let row = '';
        for (const column of headerMap.values()) {
            let noValueFound = true;
            if (column != null && column.length > 0 && column[column.length - 1][1] === i) {
                const valueTuple = column.pop();
                if (valueTuple != null && valueTuple[0] != null) {
                    row += `"${escapeDoubleQuotes(valueTuple[0])}",`;
                    noValueFound = false;
                    totalValuesInCSV++;
                }
            }
            if (noValueFound) {
                row += `${NO_VALUE},`;
                totalNoValueFound++;
            }
        }
        operation = payloads[i].operation || operation;
        if (operation === 'create' || operation === 'insert') {
            row = row.substring(0, row.length - 1);
            rows += `${row}\n`;
        }
        else {
            const uniqueIdValue = getUniqueIdValue(payloads[i], operation);
            rows += `${row}"${uniqueIdValue}"\n`;
        }
    }
    if (csvStats?.shouldLog === true) {
        csvStats.numberOfNullsInCSV = totalNoValueFound;
        csvStats.numberOfValuesInCSV = totalValuesInCSV;
    }
    return rows;
};
const getUniqueIdValue = (payload, operation) => {
    operation = payload.operation || operation;
    if (payload.enable_batching &&
        operation === 'upsert' &&
        payload.bulkUpsertExternalId &&
        payload.bulkUpsertExternalId.externalIdValue) {
        return payload.bulkUpsertExternalId.externalIdValue;
    }
    if (payload.enable_batching && operation === 'update' && payload.bulkUpdateRecordId) {
        return payload.bulkUpdateRecordId;
    }
    return NO_VALUE;
};
const buildCSVData = (payloads, uniqueIdName, operation, csvStats) => {
    const headerMap = buildHeaderMap(payloads);
    let csv = buildHeaders(headerMap);
    if (csvStats?.shouldLog === true) {
        let numberOfColumns = headerMap.size;
        if (operation !== 'insert' && operation !== 'create') {
            numberOfColumns++;
        }
        csvStats.numberOfColumns = numberOfColumns;
    }
    if (operation === 'insert') {
        csv = csv.substring(0, csv.length - 1);
    }
    csv += `${uniqueIdName}\n` + buildCSVFromHeaderMap(payloads, headerMap, payloads.length, operation, csvStats);
    return csv;
};
exports.buildCSVData = buildCSVData;
const snakeCaseToPascalCase = (key) => {
    const token = (0, camelCase_1.default)(key);
    return token.charAt(0).toUpperCase() + token.slice(1);
};
const validateInstanceURL = (instanceUrl) => {
    if (instanceUrl === undefined || instanceUrl === '') {
        throw new actions_core_1.IntegrationError('Empty Salesforce instance URL. Please login through OAuth.', 'INVALID_INSTANCE_URL', 400);
    }
    const salesforceRegex = /^(https):\/\/.*\.salesforce\.com/;
    const isValid = salesforceRegex.test(instanceUrl);
    if (isValid) {
        return instanceUrl;
    }
    throw new actions_core_1.IntegrationError('Invalid Salesforce instance URL. Please login through OAuth again.', 'INVALID_INSTANCE_URL', 400);
};
exports.validateInstanceURL = validateInstanceURL;
//# sourceMappingURL=sf-utils.js.map