"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 promises_1 = require("node:fs/promises");
const body_parser_1 = __importDefault(require("body-parser"));
const websocket_1 = require("../websocket");
const workspace_1 = require("../controllers/workspace");
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 pluginsRoot = path_1.default.resolve(openedApp.repoPath, 'remoteCode/plugins');
            try {
                const contents = yield (0, promises_1.readdir)(pluginsRoot, { withFileTypes: true });
                const dirs = contents.filter(it => it.isDirectory()).map(it => it.name);
                res.json(dirs);
            }
            catch (err) {
                if ((err === null || err === void 0 ? void 0 : err.code) === 'ENOENT') {
                    res.json([]);
                }
                else {
                    console.error("Unhandelable error", err);
                    next(err);
                }
            }
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appid/create", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            const body = {
                __LABEL_PREFIX__: req.body.labelPrefix,
                __LISTING_NAME__: req.body.listingName,
                __DISPLAY_DESCRIPTION__: req.body.displayDescription,
                __LISTING_ICON__: req.body.listingIcon,
                __PLUGIN_REGISTRY_NAME__: req.body.pluginRegistryName,
                __PLUGIN_NAME__: req.body.listingName
            };
            const name = req.body.pluginRegistryName.toLowerCase();
            const pluginRoot = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins`, name);
            try {
                yield (0, promises_1.mkdir)(path_1.default.resolve(pluginRoot, "source"), { recursive: true });
            }
            catch (err) {
                if ((err === null || err === void 0 ? void 0 : err.code) !== 'EEXIST') {
                    console.error("Unhandelable error", err);
                    next(err);
                }
            }
            const widgetFile = path_1.default.resolve(__dirname, "../templates/widget.jsx");
            const p1 = (0, promises_1.readFile)(widgetFile, { encoding: "utf-8" })
                .then(basicWidgetConfig => {
                basicWidgetConfig = basicWidgetConfig.replace(/__LABEL_PREFIX__/g, body.__LABEL_PREFIX__)
                    .replace(/__LISTING_NAME__/g, body.__LISTING_NAME__)
                    .replace(/__DISPLAY_DESCRIPTION__/g, body.__DISPLAY_DESCRIPTION__)
                    .replace(/__LISTING_ICON__/g, body.__LISTING_ICON__)
                    .replace(/__PLUGIN_REGISTRY_NAME__/g, body.__PLUGIN_REGISTRY_NAME__)
                    .replace(/__PLUGIN_NAME__/g, appId + '/' + body.__PLUGIN_NAME__);
                return (0, promises_1.writeFile)(path_1.default.resolve(pluginRoot, "source/widget.jsx"), basicWidgetConfig);
            });
            const componentFile = path_1.default.resolve(__dirname, "../templates/component.jsx");
            const p2 = (0, promises_1.cp)(componentFile, path_1.default.resolve(pluginRoot, "source/component.jsx"));
            const p3 = yield (0, promises_1.mkdir)(path_1.default.resolve(pluginRoot, "dist"), { recursive: true });
            yield Promise.all([p1, p2, p3]);
            res.status(200);
            res.end();
        }
        catch (err) {
            console.error("in POST /create", err);
            next(err);
        }
    }
    else {
        console.log("Link doesn't exist. Ignoring");
        res.status(400);
        res.end();
    }
}));
router.get('/:appid/getall', (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    // check if compiled files exist
    const appId = req.params.appid;
    try {
        const pluginBundleFilePath = yield (0, workspace_1.getPluginBundle)(appId);
        res.sendFile(pluginBundleFilePath);
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appId/compileall", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appId;
        const result = yield (0, workspace_1.compilePluginBundle)(appId);
        res.send(result);
    }
    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 {
            next(err);
        }
    }
}));
router.get("/:appid/:assetname/source", (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            const remoteCode = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}/source/component.jsx`);
            console.log(`Looking for source file: ${remoteCode}`);
            res.sendFile(remoteCode);
        }
        else {
            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 {
            console.error("Open the app first");
            res.status(500);
            res.send("in /:name/source a server error occured. Check server logs.");
        }
    }
    // return the component source code
}));
router.post("/:appid/:assetname/source", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        const code = req.body.code;
        if (openedApp) {
            const sourceFilePath = path_1.default.resolve(openedApp.repoPath, `remoteCode/plugins/${pluginName}/source/component.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: ${pluginName}`);
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        console.error("in POST /:name/source", err);
        next(err);
    }
}));
// TODO(gaurav): add ensurefolders middleware
router.delete("/:appid/:assetname", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const pluginName = req.params.assetname;
        const openedApp = (0, cliconfig_1.getOpenApp)(appId);
        if (openedApp) {
            const dirPath = path_1.default.resolve(openedApp.repoPath, 'remoteCode/plugins', pluginName);
            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);
        next(err);
    }
}));
exports.default = router;
