"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.builder = exports.desc = exports.command = void 0;
const fs = require("fs");
const ts_generator_1 = require("../codegen/generators/ts_generator");
const doc_generator_1 = require("../codegen/generators/doc_generator");
const go_generator_1 = require("../codegen/generators/go_generator");
const dbt_generator_1 = require("../codegen/generators/dbt_generator");
const utils_1 = require("../utils");
const utils_2 = require("@syftdata/common/lib/utils");
const inquirer_1 = require("inquirer");
const pkg_1 = require("../config/pkg");
const linter_1 = require("../lint/linter");
const json_server_1 = require("../watch/json_server");
const codehandler_1 = require("@syftdata/codehandler");
exports.command = 'generate [type]';
exports.desc = 'Generates client libraries, dbt and docs from Event models.';
const builder = (y) => {
    return (y
        .positional('type', {
        choices: ['ts'],
        default: 'ts'
    })
        .option('input', {
        describe: 'input folder with events.ts file.',
        default: (0, utils_1.getSchemaFolder)(),
        type: 'string'
    })
        .option('outDir', {
        describe: 'Directory to place output files',
        type: 'string'
    })
        .option('watch', {
        describe: 'Watch input folder for changes and regenerate',
        type: 'boolean'
    }));
};
exports.builder = builder;
async function getBigQueryConfig(projectId, dataset) {
    const prompts = [];
    if (projectId == null) {
        prompts.push({
            type: 'input',
            name: 'projectId',
            message: 'GCP Project ID:'
        });
    }
    if (dataset == null) {
        prompts.push({
            type: 'input',
            name: 'dataset',
            message: 'BigQuery Dataset (stores events):'
        });
    }
    const { config } = await (0, inquirer_1.prompt)(prompts);
    return {
        projectId: config.projectId,
        dataset: config.dataset
    };
}
async function getProviderConfig(destination, platform) {
    let destinationVal = '';
    if (destination == null) {
        const { answer } = await (0, inquirer_1.prompt)([
            {
                type: 'input',
                name: 'destination',
                message: 'Data Destination (Segment / Heap):'
            }
        ]);
        destinationVal = answer;
    }
    else {
        destinationVal = destination;
    }
    return {
        destination: destinationVal,
        platform
    };
}
async function innerHandler({ input, type, outDir, projectId, dataset, destination, platform }) {
    const ast = (0, codehandler_1.deserialize)([input]);
    if (ast != null) {
        if (ast.config.lintingDisabled !== true) {
            const successLint = await (0, linter_1.runLinter)([input]);
            if (!successLint) {
                return ast;
            }
        }
        if (type === 'ts') {
            const pkg = await (0, pkg_1.getClientPackage)();
            (0, ts_generator_1.generate)(ast, outDir ?? pkg.dir, pkg);
            const [currentVersion] = pkg.json.version.split('+');
            pkg.json.version = `${currentVersion}+${Date.now()}`;
            (0, pkg_1.updatePackageJson)(pkg);
        }
        else if (type === 'doc') {
            (0, doc_generator_1.generate)(ast, outDir ?? './docs');
        }
        else if (type === 'go') {
            (0, go_generator_1.generate)(ast, outDir ?? './golang');
        }
        else if (type === 'dbt') {
            const bqConfig = await getBigQueryConfig(projectId, dataset);
            const providerConfig = await getProviderConfig(destination, platform);
            (0, dbt_generator_1.generate)(ast, outDir ?? './dbt', bqConfig, providerConfig);
        }
    }
    return ast;
}
async function handler(params) {
    const { watch, input } = params;
    let ast = await innerHandler(params);
    if (watch === true) {
        (0, utils_2.logDetail)('Watching input folder for changes...');
        fs.watch(input, (eventType, filename) => {
            if (filename?.endsWith('.ts')) {
                (0, utils_2.logInfo)('Detected changes in the input folder. Regenerating...');
                innerHandler(params)
                    .then((latestAST) => {
                    ast = latestAST;
                    (0, utils_2.logInfo)('Regeneration complete.');
                })
                    .catch(() => { });
            }
        });
        (0, json_server_1.startServer)(() => ast);
    }
}
exports.handler = handler;
