"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.handler = exports.builder = exports.desc = exports.command = void 0;
const utils_1 = require("../utils");
const fs = require("fs");
const path = require("path");
const generate_1 = require("./generate");
const destination_1 = require("../init/destination");
const local_1 = require("../init/local");
const remote_1 = require("../publish/remote");
const codehandler_1 = require("@syftdata/codehandler");
const ts_morph_1 = require("ts-morph");
exports.command = 'init [platform] [product]';
exports.desc = 'Initialize Syft project. Generates Event models.';
const builder = (y) => {
    return y
        .option('apikey', {
        describe: 'Syft API key. If provided, event models are fetched from the remote server',
        type: 'string'
    })
        .option('branch', {
        describe: 'Branch to pull event models from. If not provided, the default branch is used',
        type: 'string'
    })
        .positional('platform', {
        choices: ['web', 'mobile'],
        default: 'web',
        describe: 'events are auto generated for this platform',
        type: 'string'
    })
        .positional('product', {
        choices: ['ecommerce', 'b2b'],
        describe: 'events are auto generated for the product',
        type: 'string'
    })
        .option('outDir', {
        describe: 'Directory to place model files',
        default: (0, utils_1.getSchemaFolder)(),
        type: 'string'
    });
};
exports.builder = builder;
function initalizeSchemaFolder(folder, force) {
    if (!fs.existsSync(folder)) {
        fs.mkdirSync(folder);
    }
    else {
        if (!force) {
            (0, utils_1.logError)(`:warning: Folder ${folder} exists already.`);
            (0, utils_1.logInfo)('Use --force to overwrite the folder');
            return false;
        }
        else {
            (0, utils_1.logDetail)(`--force is used. Overwriting existing ${folder}`);
        }
    }
    return true;
}
function generateSchemasFrom(ast, folder) {
    (0, utils_1.logVerbose)(`Output dir: ${folder}`);
    const lintRules = path.join(folder, 'lint/rules');
    if (!fs.existsSync(lintRules)) {
        fs.mkdirSync(lintRules, { recursive: true });
    }
    fs.copyFileSync(path.join(__dirname, '../../assets/config.ts'), path.join(folder, 'config.ts'));
    fs.copyFileSync(path.join(__dirname, '../../assets/lint/config.cjs'), path.join(folder, 'lint/config.cjs'));
    fs.copyFileSync(path.join(__dirname, '../../assets/lint/rules/required_syft_fields.js'), path.join(folder, 'lint/rules/required_syft_fields.js'));
    fs.copyFileSync(path.join(__dirname, '../../assets/lint/rules/required_tsdoc.js'), path.join(folder, 'lint/rules/required_tsdoc.js'));
    if (ast.eventSchemas.length !== 0) {
        const project = new ts_morph_1.Project({
            compilerOptions: {
                target: ts_morph_1.ScriptTarget.ES2016,
                declaration: true,
                sourceMap: true,
                module: ts_morph_1.ModuleKind.CommonJS,
                strict: false,
                removeComments: false
            }
        });
        project.createDirectory(folder);
        const sourceFile = project.createSourceFile(path.join(folder, 'events.ts'), (writer) => {
            writer.write((0, codehandler_1.serialize)(ast));
        }, { overwrite: true });
        sourceFile.saveSync();
    }
    (0, utils_1.logInfo)(`:sparkles: Models are generated successfully!`);
}
async function handler({ platform, product, outDir, apikey, branch, remote, force }) {
    (0, utils_1.logVerbose)(`Initializing Syft in ${outDir}..`);
    let ast;
    if (apikey !== undefined) {
        (0, utils_1.logVerbose)(`Pulling from ${remote}..`);
        const remoteData = await (0, destination_1.fetchRemoteData)(remote, apikey, branch);
        if (remoteData === undefined) {
            (0, utils_1.logError)(`:warning: Failed to fetch data from ${remote}`);
            return;
        }
        ast = remoteData.ast;
        initalizeSchemaFolder(outDir, force);
        (0, remote_1.writeTestSpecs)(remoteData.tests, outDir);
    }
    else {
        (0, utils_1.logVerbose)(`Generating models for ${platform}`);
        ast = (0, local_1.getEventShemas)(platform, product);
        initalizeSchemaFolder(outDir, force);
    }
    generateSchemasFrom(ast, outDir);
    (0, utils_1.logInfo)(':heavy_check_mark: Syft folder is created.');
    if (process.env.NODE_ENV !== 'test') {
        await (0, generate_1.handler)({ input: outDir, type: 'ts' });
    }
}
exports.handler = handler;
