"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.jsonParser = void 0;
const express_1 = __importDefault(require("express"));
const path_1 = __importDefault(require("path"));
const body_parser_1 = __importDefault(require("body-parser"));
const promises_1 = require("node:fs/promises");
const js_sha256_1 = require("js-sha256");
const compiler_1 = require("../controllers/compiler");
const websocket_1 = require("../websocket");
const cliconfig_1 = require("../database/cliconfig");
exports.jsonParser = body_parser_1.default.json({ limit: '50mb' });
const router = express_1.default.Router();
router.get('/:appid/list', (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            const navroot = path_1.default.resolve(openedApp.repoPath, 'remoteCode/navigators');
            const contents = yield (0, promises_1.readdir)(navroot, { withFileTypes: true });
            const dirs = contents.filter(it => it.isDirectory()).map(it => it.name);
            res.json(dirs);
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        next(err);
    }
}));
router.get("/:appid/:assetname/source", (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const navName = req.params.assetname;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            const navFile = path_1.default.resolve(openedApp.repoPath, `remoteCode/navigators/${navName}/source/index.jsx`);
            (0, websocket_1.sendLog)(`component source file path: ${navFile}`);
            res.sendFile(navFile);
        }
        else {
            (0, websocket_1.sendLog)(`Link not found, cannot send source for: ${navName}`);
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        (0, websocket_1.sendLog)("in GET /:name/source" + (err === null || err === void 0 ? void 0 : err.message));
        if ((err === null || err === void 0 ? void 0 : err.message) && (err === null || err === void 0 ? void 0 : err.errors)) {
            res.json(err);
        }
        else {
            res.status(500);
            res.send("in /:name/source a server error occured. Check server logs.");
        }
    }
}));
router.post("/:appid/:name/source", exports.jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const navName = req.params.name;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        const code = req.body.code;
        if (openedApp) {
            const sourceFilePath = path_1.default.resolve(openedApp.repoPath, `remoteCode/navigators/${navName}/source/index.jsx`);
            const results = yield (0, promises_1.writeFile)(sourceFilePath, code);
            res.json(results);
        }
        else {
            (0, websocket_1.sendLog)(`Link not found, cannot write source for: ${navName}`);
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        console.error("in POST /:name/source", err);
        res.status(500);
        res.end();
    }
}));
router.delete("/:appid/:assetname", (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const navName = req.params.assetname;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            const dirPath = path_1.default.resolve(openedApp.repoPath, 'remoteCode/navigators', navName);
            yield (0, promises_1.rm)(dirPath, { recursive: true, maxRetries: 4 });
            res.status(200);
            res.end();
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        console.error("in DELETE /:assetname", err);
        res.status(500);
        res.end();
    }
}));
// TODO(gaurav): add ensurefolders middleware
router.get('/:appid/getall', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    var _a, _b;
    // check if compiled files exist
    const appId = req.params.appid;
    const navs = (_b = (_a = req.query.navigators) === null || _a === void 0 ? void 0 : _a.split(',').filter(it => !!it)) !== null && _b !== void 0 ? _b : [];
    const openedApp = (0, cliconfig_1.getOpenApp)(appId);
    console.log(`Getting all navigators for: ${appId} ${req.query.navigators}`);
    if (openedApp && navs.length > 0) {
        const compiledDirectoryName = (0, js_sha256_1.sha256)('navigators_' + navs.join('_')).toString();
        try {
            const bundlePath = path_1.default.resolve(openedApp.repoPath, 'remoteCode/generated', compiledDirectoryName, 'dist/bundle.js');
            yield (0, promises_1.stat)(bundlePath);
            res.sendFile(bundlePath);
        }
        catch (err) {
            if ((err === null || err === void 0 ? void 0 : err.code) === 'ENOENT') {
                const compileResult = yield (0, compiler_1.compileMultipleNavCreators)(openedApp.repoPath, navs, compiledDirectoryName);
                if (!compileResult) {
                    const bundlePath = path_1.default.resolve(openedApp.repoPath, 'remoteCode/plugins', compiledDirectoryName, 'dist/bundle.js');
                    res.sendFile(bundlePath);
                }
                else {
                    res.send("Compilation failed");
                }
            }
            else {
                console.error(err);
                res.status(500);
                res.end();
            }
        }
    }
    else {
        (0, websocket_1.sendLog)(`Cannot send bundle for ${appId} as there are no navigators queried for ${req.query.navigators}`);
        res.status(404);
        res.end();
    }
}));
router.post("/:appid/create", exports.jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    console.log("creating new navigator");
    const appId = req.params.appid;
    const openedApp = (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            const name = req.body.navRegistryName.toLowerCase();
            const navRoot = path_1.default.resolve(openedApp.repoPath, `remoteCode/navigators`, name);
            const sourceFolder = path_1.default.resolve(navRoot, "source");
            yield (0, promises_1.mkdir)(sourceFolder, { recursive: true });
            const navTemplateFile = path_1.default.resolve(__dirname, "../templates/tabNavigator.jsx");
            const basicTabNav = yield (0, promises_1.readFile)(navTemplateFile, { encoding: "utf-8" });
            yield (0, promises_1.writeFile)(path_1.default.resolve(sourceFolder, "index.jsx"), basicTabNav);
            yield (0, promises_1.mkdir)(path_1.default.resolve(navRoot, "dist"), { recursive: true });
            res.status(200);
            res.end();
        }
        catch (err) {
            console.error("in POST /create", err);
            res.status(500);
            res.end();
        }
    }
    else {
        console.log("Link doesn't exist. Ignoring");
        res.status(400);
        res.end();
    }
}));
router.post("/:appid/compileall", exports.jsonParser, (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            let plugins = req.body.plugins;
            if (!plugins) {
                const dirs = yield (0, promises_1.readdir)(path_1.default.resolve(openedApp.repoPath, `remoteCode/navigators`), { withFileTypes: true });
                plugins = dirs.filter(it => it.isDirectory()).map(it => it.name);
            }
            // sendLiveUpdateRequest(appid)
            console.log("Recompiling navigators: " + plugins.join(","));
            const compiledDirectoryName = (0, js_sha256_1.sha256)('navigators_' + plugins.join('_')).toString();
            const result = yield (0, compiler_1.compileMultipleNavCreators)(openedApp.repoPath, plugins, compiledDirectoryName);
            res.send(result);
        }
        else {
            console.error("Link not found. Ignoring");
            res.status(500);
            res.end();
        }
    }
    catch (err) {
        console.error("in /compileall", err);
        if ((err === null || err === void 0 ? void 0 : err.message) && (err === null || err === void 0 ? void 0 : err.errors)) {
            res.json(err);
        }
        else {
            res.send("in /compileall a server error occured. Check server logs.");
        }
    }
}));
exports.default = router;
