"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 projectSetup_1 = require("../controllers/projectSetup");
const body_parser_1 = __importDefault(require("body-parser"));
const projectSetup_2 = require("../controllers/projectSetup");
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
const promises_1 = require("node:fs/promises");
const form_data_1 = __importDefault(require("form-data"));
const axios_1 = __importDefault(require("axios"));
const websocket_1 = require("../websocket");
const compiler_1 = require("../controllers/compiler");
const bundleUpload_1 = require("../controllers/bundleUpload");
const utils_1 = require("../utils");
const cliconfig_1 = require("../database/cliconfig");
const workspace_1 = require("../controllers/workspace");
const tools_1 = require("../controllers/agents/mcp-servers/tools");
const utils_2 = require("../utils");
const supabase_1 = require("../controllers/agents/mcp-servers/supabase");
// export const getMidUrlAppValue = () => {
//   return process.env.NODE_ENV === 'production'? 'admin/api/v2/apps' : 'api/v2/app';
// }
// const plannerAgent = new AppPlannerAgent();
exports.jsonParser = body_parser_1.default.json({ limit: '50mb' });
const router = express_1.default.Router();
router.get('/test', (req, res) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = "07a6b5be-5f8a-4273-ada1-20dceb9fa21a";
    let creds = "";
    // const creds = await supabaseConfigManager.getCreds(appId);
    // let tool = tools.projectCodeWrite[1];
    // let tool = tools.projectCodeReadForPlanner[0];
    let tool = null;
    $outer: for (let key of Object.keys(tools_1.tools)) {
        // @ts-ignore
        const toolGroup = tools_1.tools[key];
        for (let t of toolGroup)
            if ((t === null || t === void 0 ? void 0 : t.name) === "run_curl") {
                tool = t;
                break $outer;
            }
    }
    if (!(tool === null || tool === void 0 ? void 0 : tool.name)) {
        res.status(200);
        res.end("No tool found!");
    }
    else {
        if (tool.name.startsWith("supabase_")) {
            creds = yield supabase_1.supabaseConfigManager.getCreds(appId);
        }
        try {
            const result = yield tool.cb({
                // root_path: "source",
                // sql_query: "UPDATE todos SET title = 'Updated title', description = 'Updated description', is_completed = true, updated_at = NOW() WHERE id = '00000000-0000-0000-0000-000000000000';",
                curl_string: "curl --location 'https://api.themoviedb.org/3/discover/tv?include_adult=false&include_null_first_air_dates=false&language=en-US&page=1&sort_by=popularity.desc' --header 'accept: application/json' --header 'authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1ODg0YzAxZDdhYjVhZWQ0MzhlMzllMWUzMWJiOGMxNCIsIm5iZiI6MTc0ODM1OTMwMS4wMTUsInN1YiI6IjY4MzVkODg1ZWI0ZDZhOGNmMzAzN2IzNSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.1xyec4MZjgRtI_uG6DmqVH2JQdOntZZz1j7oxTVk1jU'",
                url: "https://api.themoviedb.org/3/discover/tv?include_adult=true&include_video=true&language=en-US&page=1&sort_by=popularity.desc",
                method: "GET",
                headers: {
                    "accept": "application/json",
                    "origin": "https://developer.themoviedb.org",
                    "referer": "https://developer.themoviedb.org/",
                    "Authorization": "Bearer eyJhbGciOiJIUzI1NiJ9.eyJhdWQiOiI1ODg0YzAxZDdhYjVhZWQ0MzhlMzllMWUzMWJiOGMxNCIsIm5iZiI6MTc0ODM1OTMwMS4wMTUsInN1YiI6IjY4MzVkODg1ZWI0ZDZhOGNmMzAzN2IzNSIsInNjb3BlcyI6WyJhcGlfcmVhZCJdLCJ2ZXJzaW9uIjoxfQ.1xyec4MZjgRtI_uG6DmqVH2JQdOntZZz1j7oxTVk1jU"
                },
                body: "",
                file_path: "source/component.jsx",
                line_ranges: [{ first_line: 1, last_line: 20 }],
                apptile_context: {
                    app_id: appId,
                    plugin_root: "/Users/gauravgautam/apptile-cli-home/singlepromptapp-testbed/remoteCode/plugins/todolist",
                    plugins_dir: "/Users/gauravgautam/apptile-cli-home/singlepromptapp-testbed/remoteCode/plugins",
                    supabase_creds: creds
                }
            });
            res.json(result);
        }
        catch (err) {
            res.status(500);
            res.end();
            console.error("Error when running the tool", err);
        }
    }
}));
router.get("/:appid/plannerimages", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const imageContents = (0, cliconfig_1.getImagesFromPlanner)(appId);
        res.json(imageContents);
    }
    catch (err) {
        next(err);
    }
}));
router.get(`/devices`, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const devices = yield (0, projectSetup_2.listDevices)();
        res.json(devices);
    }
    catch (err) {
        console.error("Failed to get devices");
        next(err);
    }
}));
router.post(`/:appid/bundles/:bundleid`, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const bundleId = req.params.bundleid;
    const app = yield (0, cliconfig_1.getOpenApp)(appId);
    if (app) {
        try {
            const header = (0, utils_1.makeHeadersWithCookie)(app.apptilecookie, {});
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            yield axios_1.default.put(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/deploy/${bundleId}`, {}, header);
            res.status(200);
            res.end();
        }
        catch (err) {
            console.error("Failed to publish", err);
            next(err);
        }
    }
    else {
        console.error("Opened app doesn't exist or doesn't have apptilecookie. Update database!");
        next(new Error("No app or cookie found during publishing bundle"));
    }
}));
router.post(`/:appId/runAndroid/:deviceId`, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appId;
    const deviceId = req.params.deviceId;
    try {
        (0, projectSetup_1.runAndroid)(appId, deviceId);
        res.status(201);
        res.end();
    }
    catch (err) {
        next(err);
    }
}));
router.post(`/:appId/runIOS/:deviceId`, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appId;
    const deviceId = req.params.deviceId;
    try {
        (0, projectSetup_1.runIOS)(appId, deviceId);
        res.status(201);
        res.end();
    }
    catch (err) {
        next(err);
    }
}));
router.get(`/:appid/bundles`, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    let headers = {};
    if (openedApp) {
        headers = { headers: (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {}) };
    }
    else {
        console.error("No apptilecookie found 1");
        next(new Error("No apptile cookie"));
        return;
    }
    try {
        const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
        const { data: manifest } = yield axios_1.default.get(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/manifest`, headers);
        const { data: bundles } = yield axios_1.default.get(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/bundles`, headers);
        let iosBundles = [];
        try {
            if (openedApp) {
                const entries = yield (0, promises_1.readdir)(path_1.default.resolve(openedApp.repoPath, 'remoteCode/generated/bundles/ios'), { withFileTypes: true });
                const formatter = Intl.DateTimeFormat('en-US', { timeStyle: 'short', dateStyle: 'full' });
                for (let entry of entries) {
                    if (entry.isDirectory()) {
                        try {
                            const name = new Date(parseInt(entry.name));
                            iosBundles.push({
                                name: entry.name,
                                date: formatter.format(name),
                                path: path_1.default.resolve(openedApp.repoPath, 'remoteCode/generated/bundles/ios', entry.name)
                            });
                        }
                        catch (err) { }
                    }
                }
            }
        }
        catch (err) {
            (0, websocket_1.sendLog)("Error in trying to get local ios bundles: " + (err === null || err === void 0 ? void 0 : err.message));
        }
        if (openedApp) {
            res.json({ openedApp, manifest, bundles, iosBundles });
        }
        else {
            res.status(404);
            res.end();
        }
    }
    catch (err) {
        res.render('error', { message: err === null || err === void 0 ? void 0 : err.message });
    }
}));
router.post('/:appid/build/:os/:mode', (req, res, next) => {
    const appId = req.params.appid;
    const os = req.params.os;
    const mode = req.params.mode;
    try {
        if ((0, projectSetup_1.narrowOSName)(os) && (0, projectSetup_1.narrowBuildMode)(mode)) {
            const deviceId = req.query.deviceId;
            (0, projectSetup_1.buildApp)(appId, os, mode, deviceId);
            res.status(201);
            res.end();
        }
        else {
            console.error("Wrong os name or build mode");
            res.status(400);
            res.end();
        }
    }
    catch (err) {
        console.error("Build failed");
        next(err);
    }
});
router.delete('/killmetro', (req, res) => {
    (0, projectSetup_1.killMetro)();
    res.status(200);
    res.end();
});
router.get('/close-install-popup', (req, res) => {
    res.render('installPopup.pug', { visible: false, valid: false });
});
router.post("/:appid/uploadMobileBundle/:bundleName/:os", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appId = req.params.appid;
        const bundleName = req.params.bundleName;
        const os = req.params.os;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
        if (!openedApp) {
            console.error("No apptilecookie found");
            res.status(404);
            res.end();
            return;
        }
        if ((0, projectSetup_1.narrowOSName)(os)) {
            try {
                yield (0, bundleUpload_1.uploadMobileBundle)(appId, bundleName, os, openedApp.apptilecookie);
                res.status(200);
                res.end();
            }
            catch (error) {
                // Check if this was a bundle retrieval error, in which case we want to match original behavior
                if (error && error.message && typeof error.message === 'string' && error.message.includes('Failed to retrieve bundle')) {
                    console.error("Failed to retrieve bundle:", error);
                    res.status(500);
                    res.end();
                    return;
                }
                console.error("Error uploading mobile bundle:", error);
                next(error);
            }
        }
        else {
            next(new Error("Cannot upload bundle for os name: " + os));
        }
    }
    catch (err) {
        console.error("in uploadMobileBundle", err);
        next(err);
    }
}));
router.get("/:appid/commits", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    let headers = {};
    if (openedApp) {
        headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {});
    }
    else {
        console.error("openedApp: ", openedApp);
        next(new Error("No apptilecookie found 3"));
        return;
    }
    try {
        const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
        const commits = yield axios_1.default.get(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/commits`, headers);
        res.json(commits.data);
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appid/pushLogs", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const payload = req.body;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    let headers = {};
    if (openedApp) {
        headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {});
    }
    else {
        next(new Error("No apptilecookie found 4"));
        return;
    }
    const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
    try {
        // ["appId", "androidBundleId", "iosBundleId", "pluginsBundleId", "navigatorsBundleId", "publishedCommitId", "comment"]
        yield axios_1.default.post(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/pushLogs`, {
            appId,
            androidBundleId: parseInt(payload.androidBundleId),
            iosBundleId: parseInt(payload.iosBundleId),
            pluginsBundleId: parseInt(payload.pluginsBundleId),
            navigatorsBundleId: parseInt(payload.navigatorsBundleId),
            publishedCommitId: parseInt(payload.publishedCommitId),
            comment: payload.comment
        }, headers);
        res.json({});
    }
    catch (err) {
        next(err);
    }
}));
router.post("/:appid/refreshIntegrations", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    // TODO(gaurav): this logic should be in a controller and the table 
    // should have new columns for all the columns that are being misused here
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        const integrations = req.body.integrations;
        (0, websocket_1.sendLog)("Refreshing integrations");
        try {
            // Check if a sdk integration has platformtype of apptilesdk
            let sdkIntegrations = [];
            for (let i = 0; i < integrations.length; ++i) {
                const integration = integrations[i];
                if (integration.packageLocation) {
                    sdkIntegrations.push(integration);
                }
            }
            const packageJsonNewEntries = {};
            // Codegen the relevant files
            for (let i = 0; i < sdkIntegrations.length; ++i) {
                const packageName = sdkIntegrations[i].integrationCode;
                const camelCasePackageName = (0, utils_1.toCamelCase)(packageName);
                const gitRepo = sdkIntegrations[i].packageLocation;
                (0, websocket_1.sendLog)(`Integration: ${packageName}: ${gitRepo}`);
                packageJsonNewEntries[packageName] = gitRepo;
                yield (0, promises_1.mkdir)(path_1.default.resolve(openedApp.repoPath, 'remoteCode/plugins', packageName, 'source'), { recursive: true });
                const pluginsLinkingFile = path_1.default.resolve(openedApp.repoPath, 'remoteCode/plugins', packageName, 'source/widget.jsx');
                yield (0, promises_1.writeFile)(pluginsLinkingFile, `import ${camelCasePackageName} from "${packageName}";
export default ${camelCasePackageName};\n`);
            }
            const existingPackageJSON = yield (0, promises_1.readFile)(path_1.default.resolve(openedApp.repoPath, 'package.json'), { encoding: 'utf8' });
            const parsedPackageJSON = JSON.parse(existingPackageJSON);
            let pkgJSONUpdated = false;
            for (let pkg in packageJsonNewEntries) {
                if (parsedPackageJSON.dependencies[pkg] != packageJsonNewEntries[pkg]) {
                    parsedPackageJSON.dependencies[pkg] = packageJsonNewEntries[pkg];
                    pkgJSONUpdated = true;
                }
            }
            if (pkgJSONUpdated) {
                // write updated package.json
                const updatedPkgJson = JSON.stringify(parsedPackageJSON, null, 2);
                (0, websocket_1.sendLog)(`Updated package.json\n${updatedPkgJson}`);
                yield (0, promises_1.writeFile)(path_1.default.resolve(openedApp.repoPath, 'package.json'), updatedPkgJson);
                // run npm install
                yield (0, projectSetup_1.npmInstall)(openedApp.repoPath);
            }
            else {
                (0, websocket_1.sendLog)("No updates required to package.json");
            }
            res.status(201);
            res.end();
        }
        catch (err) {
            (0, websocket_1.sendLog)("Failed while refreshing integrations " + (err === null || err === void 0 ? void 0 : err.message));
            next(err);
        }
    }
    else {
        res.status(404);
        res.end();
    }
}));
router.post("/:appid/uploadWebBundle", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const appid = req.params.appid;
        const openedApp = yield (0, cliconfig_1.getOpenApp)(appid);
        const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appid);
        const { err: pluginErr, res: pluginsBundle } = yield (0, projectSetup_2.currentPluginsBundle)(appid);
        const { err: navErr, res: navigatorsBundle } = yield (0, projectSetup_2.currentNavigatorsBundle)(appid);
        if (pluginErr || navErr) {
            console.error(pluginErr, navErr);
            res.render('error', { message: 'Failed to get plugin or navigator bundle' });
        }
        else {
            const { err, gitsha, sdksha } = yield (0, projectSetup_1.getGitShas)(appid);
            if (err) {
                res.render('error', { message: 'Failed to get git shas' });
                return;
            }
            else if (gitsha && sdksha) {
                // Upload plugins bundle
                let formData = new form_data_1.default();
                formData.append('file', (0, fs_1.createReadStream)(pluginsBundle));
                formData.append('uploadDestination', 'plugins');
                formData.append('gitsha', gitsha);
                formData.append('sdksha', sdksha);
                formData.append('tag', 'sometag');
                let headers = {};
                if (openedApp) {
                    headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, formData.getHeaders());
                }
                else {
                    next(new Error("Failed to get apptilecookie"));
                    return;
                }
                let res = yield axios_1.default.post(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appid}/upload`, formData, headers);
                if (res.status >= 400) {
                    try {
                        const erroMessage = res.data;
                        throw new Error("Failed to upload " + erroMessage);
                    }
                    catch (err) {
                        console.error("Unprocessable error: ", err);
                        throw err;
                    }
                }
                // Upload navigator bundle
                formData = new form_data_1.default();
                formData.append('file', (0, fs_1.createReadStream)(navigatorsBundle));
                formData.append('uploadDestination', 'navigators');
                formData.append('gitsha', gitsha);
                formData.append('sdksha', sdksha);
                formData.append('tag', 'sometag');
                headers = (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, formData.getHeaders());
                res = yield axios_1.default.post(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appid}/upload`, formData, headers);
                if (res.status >= 400) {
                    try {
                        const erroMessage = res.data;
                        throw new Error("Failed to upload " + erroMessage);
                    }
                    catch (err) {
                        console.error("Unprocessable error: ", err);
                        throw err;
                    }
                }
            }
            else {
                throw new Error("Invalid code path");
            }
            res.status(200);
            res.end();
            // render the bundles maybe
        }
    }
    catch (err) {
        console.error("in ubloadWebBundles", err);
        next(err);
    }
}));
router.post("/:appid/bundleJsIOS", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            yield (0, compiler_1.generatIOSBundle)(openedApp.repoPath);
            res.status(200).json({
                message: "iOS Bundle generation complete!",
            });
        }
        catch (err) {
            next(err);
        }
    }
    else {
        res.status(404);
        res.end();
    }
}));
router.post("/:appid/bundleJsAndroid", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    const appId = req.params.appid;
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            yield (0, compiler_1.generatAndroidBundle)(openedApp.repoPath);
            res.send(200).json({
                message: "Android Bundle generation complete!",
            });
        }
        catch (err) {
            next(err);
        }
    }
    else {
        res.status(404);
        res.end();
    }
}));
router.post("/:appid/generatePreviewDraft", exports.jsonParser, (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    console.log("in generatePreviewDraft", req.body);
    const appId = req.params.appid;
    const forkId = req.body.forkId;
    const branchName = req.body.branchName;
    const publishedCommitId = req.body.publishedCommitId;
    console.log("in generatePreviewDraft", appId, forkId, branchName, publishedCommitId);
    const openedApp = yield (0, cliconfig_1.getOpenApp)(appId);
    if (openedApp) {
        try {
            yield (0, projectSetup_1.npmInstall)(openedApp.repoPath);
            // Generate bundles for both platforms
            const [iosBundle, androidBundle] = yield Promise.all([
                (0, compiler_1.generatIOSBundle)(openedApp.repoPath),
                (0, compiler_1.generatAndroidBundle)(openedApp.repoPath),
            ]);
            const iosTimestamp = iosBundle.bundleDestination.split("/").at(-2);
            const androidTimestamp = androidBundle.bundleDestination
                .split("/")
                .at(-2);
            console.log("iosTimestamp", iosTimestamp);
            console.log("androidTimestamp", androidTimestamp);
            // Upload both bundles to the server
            const [iosResult, androidResult] = yield Promise.all([
                (0, bundleUpload_1.uploadMobileBundle)(appId, iosTimestamp, "ios", openedApp.apptilecookie),
                (0, bundleUpload_1.uploadMobileBundle)(appId, androidTimestamp, "android", openedApp.apptilecookie),
            ]);
            const apptileConfig = yield (0, workspace_1.getAppConfigsFromFS)(appId);
            const draftResult = yield axios_1.default.put(`${apptileConfig.APPTILE_BACKEND_URL}/${(0, utils_2.getMidUrlAppValue)()}/${appId}/fork/${forkId}/branch/${branchName}/PreviewAppDraft`, {
                androidBundleUrlStatus: "done",
                iosBundleUrlStatus: "done",
                iosBundleUrl: iosResult.data.cdnlink,
                androidBundleUrl: androidResult.data.cdnlink,
                publishedCommitId,
            }, (0, utils_1.makeHeadersWithCookie)(openedApp.apptilecookie, {}));
            if (draftResult.status >= 400) {
                try {
                    const errorMessage = draftResult.data;
                    throw new Error(`Failed to create draft: ${errorMessage}`);
                }
                catch (err) {
                    console.error("Unprocessable error:", err);
                    throw err;
                }
            }
            res.status(200).json({
                message: "Preview draft generated and uploaded successfully for both platforms",
                ios: iosResult.data,
                android: androidResult.data,
            });
        }
        catch (err) {
            console.error("Error generating preview draft:", err);
            next(err);
        }
    }
    else {
        res.status(404);
        res.end();
    }
}));
function buildFileTree(name, fullPath, depth) {
    return __awaiter(this, void 0, void 0, function* () {
        try {
            const entries = yield (0, promises_1.readdir)(fullPath, { withFileTypes: true });
            const contents = [];
            for (let i = 0; i < entries.length; ++i) {
                const entry = entries[i];
                if (!['.DS_Store', 'idb-applications'].includes(entry.name)) {
                    if (entry.isDirectory()) {
                        if (depth > 1) {
                            const subtree = yield buildFileTree(entry.name, path_1.default.resolve(fullPath, entry.name), depth - 1);
                            contents.push(subtree);
                        }
                        else {
                            contents.push({
                                name: entry.name,
                                fullPath: path_1.default.resolve(fullPath, entry.name),
                                type: 'directory',
                                contents: []
                            });
                        }
                    }
                    else {
                        contents.push({
                            name: entry.name,
                            fullPath,
                            type: 'file',
                            contents: []
                        });
                    }
                }
            }
            return {
                name,
                fullPath,
                type: 'directory',
                contents
            };
        }
        catch (err) {
            if (err.code === 'ENOTDIR') {
                return {
                    name,
                    fullPath,
                    type: 'file',
                    contents: []
                };
            }
            else {
                console.error("Failed to build tree rooted at: ", err);
                return {
                    name,
                    fullPath,
                    type: 'unknown',
                    contents: []
                };
            }
        }
    });
}
router.get("/explore/:path/:depth", (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
    try {
        const depth = parseInt(decodeURIComponent(req.params.depth));
        const pathToExplore = decodeURIComponent(req.params.path);
        const rootPath = path_1.default.resolve(pathToExplore);
        const tree = yield buildFileTree(pathToExplore, rootPath, depth);
        res.json(tree);
    }
    catch (err) {
        console.error("Failed to explore: ", err);
        next(err);
    }
}));
exports.default = router;
