"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const mablApi_1 = require("@mablhq-internal/runtime/mablApi");
const mablApiClientFactory_1 = require("@mablhq-internal/runtime/api/mablApiClientFactory");
const cliUtil_1 = require("@mablhq-internal/runtime/core/cliUtil");
const flowResolver_1 = require("@mablhq-internal/runtime/util/flowResolver");
const js_yaml_1 = require("js-yaml");
const constants_1 = require("@mablhq-internal/runtime/core/constants");
const constants_2 = require("../../constants");
const execution_1 = require("@mablhq-internal/runtime/execution");
const fileUtil_1 = require("../../commandUtil/fileUtil");
const ApiTestUtils_1 = require("@mablhq-internal/runtime/core/execution/ApiTestUtils");
const os = require('os');
const JSON_REPLACER = null;
exports.command = `export <${constants_1.CommandArgId}>`;
exports.describe = 'Export a mabl flow in a specified file format';
exports.builder = (yargs) => {
    yargs
        .positional(constants_1.CommandArgId, {
        describe: 'flow id to export',
        type: 'string',
    })
        .option(constants_1.CommandArgFormat, {
        alias: 'fmt',
        default: 'yaml',
        describe: `Specify a format for the flow export`,
        choices: [
            constants_1.OutputFormats.Json,
            constants_1.OutputFormats.Yaml,
            constants_1.OutputFormats.Csv,
            constants_1.OutputFormats.Postman,
        ],
    })
        .option(constants_2.CommandArgDetailLevel, {
        default: 'simple',
        hidden: true,
        nargs: 1,
        type: 'string',
    })
        .option(constants_1.CommandArgMablBranch, {
        describe: 'Which branch of the flow to export',
        nargs: 1,
        type: 'string',
    });
};
exports.handler = (0, cliUtil_1.failWrapper)(pullFlow);
async function pullFlow(parsed) {
    const flowId = parsed.id;
    const format = parsed.format;
    const detailLevel = parsed[constants_2.CommandArgDetailLevel];
    const apiClient = await mablApiClientFactory_1.MablApiClientFactory.createApiClient();
    const branchName = parsed['mabl-branch'] ?? constants_1.DefaultBranchName;
    const flow = await apiClient.getFlow(flowId, branchName);
    const nestedFlows = await (0, flowResolver_1.resolveAllNestedFlowReferences)([flow], apiClient, branchName);
    switch (format) {
        case constants_1.OutputFormats.Csv:
            dumpToCsv(flow, nestedFlows);
            break;
        case constants_1.OutputFormats.Postman:
            if (flow.flow_type !== mablApi_1.FlowTypeEnum.Api) {
                throw new Error('Only API flows can be exported as Postman collections.');
            }
            await dumpToPostmanCollection(flow, apiClient);
            break;
        case constants_1.OutputFormats.Json:
        case constants_1.OutputFormats.Yaml:
        default:
            dumpYamlOrJsonToFile(format, flow, nestedFlows, detailLevel);
            break;
    }
}
function dumpYamlOrJsonToFile(type, flow, nestedFlows, detailLevel) {
    const flowConfig = new execution_1.FlowConfig(flow, false, nestedFlows);
    const configGenerated = detailLevel === constants_2.DetailLevelFormats.Full
        ? flowConfig.generateConfigFile()
        : flowConfig.generateSimpleFormat();
    switch (type) {
        case constants_1.OutputFormats.Yaml:
            const yaml = (0, js_yaml_1.dump)(configGenerated, { skipInvalid: false });
            (0, fileUtil_1.writeExportedEntityToFile)(yaml, 'yml', flow.id);
            break;
        case constants_1.OutputFormats.Json:
            (0, fileUtil_1.writeExportedEntityToFile)(JSON.stringify(configGenerated, JSON_REPLACER, 2), 'json', flow.id);
            break;
        default:
            throw new Error(`Invalid Type supplied for exporting flow: ${type}`);
    }
}
function dumpToCsv(flow, nestedFlows) {
    const flowConfig = new execution_1.FlowConfig(flow, false, nestedFlows);
    const output = flowConfig.generateSimpleCsv();
    (0, fileUtil_1.writeExportedEntityToFile)(output.join(os.EOL), 'csv', flow.id);
}
async function dumpToPostmanCollection(flow, apiClient) {
    const collection = await (0, ApiTestUtils_1.exportPostmanFlowAsCollection)(flow, (snippetInvariantId) => apiClient.getSnippet(snippetInvariantId));
    (0, fileUtil_1.writeExportedEntityToFile)(JSON.stringify(collection, JSON_REPLACER, 2), 'json', flow.id);
}
