"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());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.CommandController = void 0;
const CommandView_1 = require("../views/CommandView");
const file_search_1 = require("../utils/file-search");
class CommandController {
    constructor({ systemPromptController, conversationHistoryController, stateController, tokenController, }) {
        this.AVAILABLE_COMMANDS = [
            "/find",
            "/f",
            "/find-add",
            "/fa",
            "/add",
            "/remove-file",
            "/rf",
            "/remove-file-all",
            "/rfa",
            "/list-files",
            "/lf",
            "/reset-conversation",
            "/rc",
            "/reset-all",
            "/ra",
            "/new",
            "/n",
            "/save",
            "/s",
            "/save-overwrite",
            "/so",
            "/save-cache",
            "/sc",
            "/save-cache-overwrite",
            "/sco",
            "/load",
            "/l",
            "/delete",
            "/d",
            "/delete-all",
            // "/da", // not enabled due to risk of accidental deletion
            "/rename",
            "/rn",
            "/list-saves",
            "/ls",
            "/token-report",
            "/tr",
            "/token-limit",
            "/tl",
            "/token-files",
            "/tf",
            "/verbose",
            "/debug",
            "/cwd",
            "/pwd",
        ];
        this.commandView = new CommandView_1.CommandView();
        this.systemPromptController = systemPromptController;
        this.conversationHistoryController = conversationHistoryController;
        this.stateController = stateController;
        this.tokenController = tokenController;
    }
    isCommandAvailable(command) {
        return this.AVAILABLE_COMMANDS.includes(command);
    }
    // main command handler
    handleCommand(commandInput) {
        return __awaiter(this, void 0, void 0, function* () {
            const cmdArry = commandInput.split(" ");
            const cmd = cmdArry[0];
            const incl = (...commands) => commands.includes(cmd);
            if (!this.isCommandAvailable(cmd)) {
                this.commandView.headerRender(`**${cmd}** is not a valid command`);
            }
            else if (incl("/f", "/find")) {
                yield this.handleFileFindByPatterns(cmdArry);
            }
            else if (incl("/fa", "/find-add", "/add")) {
                yield this.handleFileAddByPatterns(cmdArry);
            }
            else if (incl("/rf", "/remove-file")) {
                yield this.handleRemoveFileByPatterns(cmdArry);
            }
            else if (incl("/remove-file-all", "/rfa")) {
                yield this.handleRemoveFileAll();
            }
            else if (incl("/list-files", "/lf")) {
                yield this.handleListFilePaths();
            }
            else if (incl("/reset-conversation", "/rc")) {
                yield this.handleResetConversation();
            }
            else if (incl("/reset-all", "/ra")) {
                yield this.handleResetAll();
            }
            else if (incl("/token-report", "/tr")) {
                yield this.handleTokenReport();
            }
            else if (incl("/token-files", "/tf")) {
                yield this.handleTokenFiles();
            }
            else if (incl("/new", "/n")) {
                yield this.handleNewState(cmdArry);
            }
            else if (incl("/save", "/s")) {
                yield this.handleSaveState(cmdArry);
            }
            else if (incl("/save-overwrite", "/so")) {
                yield this.handleSaveOverwrite(cmdArry);
            }
            else if (incl("/save-cache", "/sc")) {
                yield this.handleSaveFromCache(cmdArry);
            }
            else if (incl("/save-cache-overwrite", "/sco")) {
                yield this.handleSaveFromCacheOverwrite(cmdArry);
            }
            else if (incl("/load", "/l")) {
                yield this.handleLoadState(cmdArry);
            }
            else if (incl("/delete", "/d")) {
                yield this.handleDeleteState(cmdArry);
            }
            else if (incl("/delete-all" /*, "/da"*/)) {
                yield this.stateController.deleteAllStates();
            }
            else if (incl("/rename", "/rn")) {
                yield this.handleRename(cmdArry);
            }
            else if (incl("/list-saves", "/ls")) {
                yield this.stateController.listSavedStates();
            }
            else if (incl("/token-limit", "/tl")) {
                yield this.handleTokenLimit(cmdArry);
            }
            else if (incl("/cwd", "/pwd")) {
                // NOTE: This is for debugging purposes only
                yield this.commandView.render(this.commandView.genericStyle(process.cwd()));
            }
            else {
                this.commandView.headerRender(`**${cmdArry[0]}** has not yet been implemented`);
            }
        });
    }
    handleNewState(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const newStateName = cmdArry[1];
            if (!newStateName) {
                this.commandView.renderInvalidCommand(["<new-name>"]);
                return;
            }
            const newStateCallback = () => __awaiter(this, void 0, void 0, function* () {
                yield this.conversationHistoryController.resetConversationHistory();
                yield this.systemPromptController.removeAllFilePaths();
                yield this.tokenController.resetConversationLimit();
            });
            yield this.stateController.newStateInterface({
                newStateName,
                newStateCallback,
                conversationHistory: yield this.conversationHistoryController.getConversationHistory(),
                trackedFiles: yield this.systemPromptController.getFilePaths(),
                limit: yield this.tokenController.getConversationLimit(),
            });
        });
    }
    handleRename(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const newName = cmdArry[1];
            if (!newName) {
                this.commandView.renderInvalidCommand(["<new-name>"]);
                return;
            }
            yield this.stateController.renameCurrentState(newName);
        });
    }
    handleSaveState(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const saveName = cmdArry[1];
            return this.stateController.saveStateInterface({
                saveName,
                overwrite: false,
                conversationHistory: yield this.conversationHistoryController.getConversationHistory(),
                trackedFiles: yield this.systemPromptController.getFilePaths(),
                limit: yield this.tokenController.getConversationLimit(),
            });
        });
    }
    handleSaveOverwrite(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const saveName = cmdArry[1];
            if (!saveName) {
                this.commandView.renderInvalidCommand(["<save-name>"]);
                return;
            }
            return this.stateController.saveStateInterface({
                saveName,
                overwrite: true,
                conversationHistory: yield this.conversationHistoryController.getConversationHistory(),
                trackedFiles: yield this.systemPromptController.getFilePaths(),
                limit: yield this.tokenController.getConversationLimit(),
            });
        });
    }
    handleSaveFromCache(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const saveName = cmdArry[1];
            if (!saveName) {
                this.commandView.renderInvalidCommand(["<save-name>"]);
                return;
            }
            yield this.stateController.moveCacheToSaveInterface({
                saveName,
                overwrite: false,
            });
        });
    }
    handleSaveFromCacheOverwrite(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const saveName = cmdArry[1];
            if (!saveName) {
                this.commandView.renderInvalidCommand(["<save-name>"]);
                return;
            }
            yield this.stateController.moveCacheToSaveInterface({
                saveName,
                overwrite: true,
            });
        });
    }
    handleLoadState(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const loadName = cmdArry[1];
            if (!loadName) {
                this.commandView.renderInvalidCommand(["<load-name>"]);
                return;
            }
            const loadStateCallback = (conversationHistory, trackedFiles, limit) => __awaiter(this, void 0, void 0, function* () {
                yield this.conversationHistoryController.resetConversationHistory();
                yield this.systemPromptController.removeAllFilePaths();
                yield this.conversationHistoryController.setConversationHistory(conversationHistory);
                yield this.systemPromptController.addFilePaths(trackedFiles);
                yield this.tokenController.setConversationLimit(limit);
            });
            // load state interface needs
            yield this.stateController.loadStateInterface({
                loadName,
                loadStateCallback,
                conversationHistory: yield this.conversationHistoryController.getConversationHistory(),
                trackedFiles: yield this.systemPromptController.getFilePaths(),
                limit: yield this.tokenController.getConversationLimit(),
            });
        });
    }
    handleDeleteState(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            const deleteName = cmdArry[1];
            if (!deleteName) {
                this.commandView.renderInvalidCommand(["<delete-name>"]);
                return;
            }
            yield this.stateController.deleteState(deleteName);
        });
    }
    handleResetConversation(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.conversationHistoryController.resetConversationHistory();
            render &&
                this.commandView.headerRender("Conversation has been **reset** 💬");
        });
    }
    handleFileAddByPatterns(cmdArry, render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const patterns = Array.from(new Set(cmdArry.slice(1)));
            if (cmdArry.length < 2) {
                this.commandView.renderInvalidCommand(["<glob1>", "<glob2>"]);
                return;
            }
            const patternsFilePathsObj = yield this.handleFileFindByPatterns(["", ...patterns], false);
            const existingFilePaths = yield this.systemPromptController.getFilePaths();
            const outersectionFPs = patternsFilePathsObj.filePaths.filter((fp) => !existingFilePaths.includes(fp));
            yield this.systemPromptController.addFilePaths(outersectionFPs);
            render && this.commandView.renderFileAdd(patternsFilePathsObj);
        });
    }
    handleRemoveFileByPatterns(cmdArry, render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const patternsToRemove = Array.from(new Set(cmdArry.slice(1)));
            if (cmdArry.length < 2) {
                this.commandView.renderInvalidCommand(["<glob1>", "<glob2>"]);
                return;
            }
            // New code...
            // We need to get the available paths that pertain to the incoming patterns.
            const patternToRemoveFilePathObj = yield this.handleFileFindByPatterns(["", ...patternsToRemove], false);
            const existingFilePaths = yield this.systemPromptController.getFilePaths();
            const intersectionFPs = patternToRemoveFilePathObj.filePaths.filter((fp) => existingFilePaths.includes(fp));
            yield this.systemPromptController.removeFilePaths(intersectionFPs);
            render &&
                this.commandView.renderRemoveFile({
                    pattern: patternsToRemove.join(" "),
                    filePaths: intersectionFPs,
                });
        });
    }
    handleRemoveFileAll(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.systemPromptController.removeAllFilePaths();
            render &&
                this.commandView.headerRender(`All files have been **un tracked** 🗑️`);
        });
    }
    handleResetAll(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.handleResetConversation(render);
            yield this.handleRemoveFileAll(render);
        });
    }
    handleListFilePaths(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const filePaths = yield this.systemPromptController.getFilePaths();
            render && this.commandView.renderListFilePaths(filePaths);
        });
    }
    handleFileFindByPatterns(cmdArry, render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            const patterns = Array.from(new Set(cmdArry.slice(1)));
            if (cmdArry.length < 2) {
                this.commandView.renderInvalidCommand(["<glob1>", "<glob2>"]);
                return {};
            }
            // glob patterns care about order when negation is involved
            const patternFilePathObj = {
                pattern: patterns.join(" "),
                filePaths: yield (0, file_search_1.findFilesWithPatterns)(patterns),
            };
            render && this.commandView.renderFindByPaths(patternFilePathObj);
            return patternFilePathObj;
        });
    }
    handleTokenReport(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.tokenController.handleTokenReport(render);
            // render && this.commandView.renderTokenReport(tokenReport);
        });
    }
    handleTokenLimit(cmdArry) {
        return __awaiter(this, void 0, void 0, function* () {
            // const tokenLimit = await this.tokenController.getTokenLimit();
            if (cmdArry.length !== 2) {
                this.commandView.renderInvalidCommand(["<number>"]);
                return;
            }
            this.tokenController.handleSetConversationLimit(cmdArry[1]);
        });
    }
    handleTokenFiles(render = true) {
        return __awaiter(this, void 0, void 0, function* () {
            // const tokenFiles = await this.tokenController.getTokenFiles();
            render &&
                this.commandView.headerRender("unavailable command **/token-files**");
        });
    }
}
exports.CommandController = CommandController;
