"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sanitizeCsvCellInput = sanitizeCsvCellInput;
exports.desanitizeCsvCellOutput = desanitizeCsvCellOutput;
exports.parseCsvScenarios = parseCsvScenarios;
exports.csvScenarioFormatToScenarios = csvScenarioFormatToScenarios;
exports.parseJsonScenarios = parseJsonScenarios;
exports.jsonToScenarios = jsonToScenarios;
exports.inferFileFormat = inferFileFormat;
exports.isScenarioArray = isScenarioArray;
exports.variableRowAsScenario = variableRowAsScenario;
const constants_1 = require("../core/constants");
const path_1 = require("path");
const fs_1 = __importDefault(require("fs"));
const csv_parser_1 = __importDefault(require("csv-parser"));
const MALICIOUS_LINE_PREFIX_MATCHER = /^([+\-@=])/;
const SANITIZED_LINE_PREFIX_MATCHER = /^(`[+\-@=])/;
function sanitizeCsvCellInput(input) {
    if (!input) {
        return '';
    }
    return MALICIOUS_LINE_PREFIX_MATCHER.test(input)
        ? `\`${input}`.trim()
        : input.trim();
}
function desanitizeCsvCellOutput(input) {
    if (!input) {
        return '';
    }
    return SANITIZED_LINE_PREFIX_MATCHER.test(input)
        ? input.slice(1).trim()
        : input.trim();
}
var AllowedInputExtensions;
(function (AllowedInputExtensions) {
    AllowedInputExtensions["Csv"] = ".csv";
    AllowedInputExtensions["Json"] = ".json";
})(AllowedInputExtensions || (AllowedInputExtensions = {}));
async function parseCsvScenarios(fileName) {
    const readCsv = await fileToCsvScenarioFormat(fileName);
    return csvScenarioFormatToScenarios(readCsv);
}
async function fileToCsvScenarioFormat(fileName) {
    const csvInput = [];
    await new Promise((resolve) => {
        fs_1.default.createReadStream(fileName)
            .pipe((0, csv_parser_1.default)())
            .on('data', (data) => csvInput.push(data))
            .on('end', () => resolve());
    });
    return csvInput;
}
function csvScenarioFormatToScenarios(input) {
    if (input.length === 0) {
        return [];
    }
    return input.map((rowItem) => ({
        id: rowItem[constants_1.SCENARIO_ID_HEADER] || undefined,
        name: desanitizeCsvCellOutput(rowItem[constants_1.SCENARIO_NAME_HEADER]),
        variables: Object.entries(rowItem)
            .filter(([key, _]) => key !== constants_1.SCENARIO_NAME_HEADER && key !== constants_1.SCENARIO_ID_HEADER)
            .map(([key, value]) => ({
            name: desanitizeCsvCellOutput(key),
            value: desanitizeCsvCellOutput(value),
        })),
    }));
}
function parseJsonScenarios(fileName) {
    const readJson = fs_1.default.readFileSync(fileName, 'utf-8');
    return jsonToScenarios(readJson);
}
function jsonToScenarios(input) {
    const parsedJson = JSON.parse(input);
    if (isScenarioArray(parsedJson)) {
        return parsedJson;
    }
    throw Error('Json input was not formatted correctly');
}
function inferFileFormat(fileName) {
    const extension = (0, path_1.extname)(fileName);
    switch (extension) {
        case AllowedInputExtensions.Csv:
            return constants_1.OutputFormats.Csv;
        case AllowedInputExtensions.Json:
            return constants_1.OutputFormats.Json;
        default:
            throw new Error('The file format could be inferred from the extension, please specify a format for your input data.');
    }
}
function isScenario(arg) {
    return ((typeof arg.id === 'string' || arg.id === undefined) &&
        typeof arg.name === 'string' &&
        Array.isArray(arg.variables) &&
        arg.variables.every((col) => typeof col.name === 'string' && typeof col.value === 'string'));
}
function isScenarioArray(arg) {
    return Array.isArray(arg) && arg.every((scenario) => isScenario(scenario));
}
function variableRowAsScenario(variableRow) {
    if (isScenario(variableRow)) {
        return variableRow;
    }
    return {
        id: variableRow.id,
        table_id: variableRow.table_id,
        created_time: variableRow.created_time,
        created_by_id: variableRow.created_by_id,
        last_updated_time: variableRow.last_updated_time,
        last_updated_by_id: variableRow.last_updated_by_id,
        workspace_id: variableRow.organization_id,
        name: variableRow.scenario_id,
        variables: variableRow.row,
    };
}
