"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.SystemPromptModel = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const PREFIX_INSTRUCTION = `You are a expert coding AI. You will answer queries provided to you in a short and concise manner. You will receive a list of files and their contents and their paths. Your task is to give clear and concise answers to any queries provided by the human given the files you are provided with. The files will given to you in the following format:

Example format:
===============
FILE: <filename>
ABSOLUTE_PATH: <file absolute path>
CONTENT:
---------------
<file content>
---------------
===============

Okay, here are the files:
`;
const SUFFIX_INSTRUCTION = `The files that I have given you above somehow interact with each other. Give clear, short and concise answers based on them`;
class SystemPromptModel {
    constructor(_filePaths = []) {
        this._filePaths = _filePaths;
        this.prefixInstruction = PREFIX_INSTRUCTION;
        this.suffixInstruction = SUFFIX_INSTRUCTION;
        this._filePaths = _filePaths;
    }
    get filePaths() {
        return [...this._filePaths];
    }
    resetFilePaths() {
        this._filePaths = [];
    }
    addFilePath(filePath) {
        this._filePaths.push(filePath);
    }
    removeFilePath(filePath) {
        const index = this._filePaths.indexOf(filePath);
        if (index > -1) {
            this._filePaths.splice(index, 1);
        }
    }
    getFilePathsAndContents() {
        return __awaiter(this, void 0, void 0, function* () {
            // NOTE: This is useful for token counting and general debugging
            return yield this.filesToObject();
        });
    }
    getSystemPromptString() {
        return __awaiter(this, void 0, void 0, function* () {
            // if there are no filePaths, return a "chat mode" system prompt.
            if (this._filePaths.length === 0) {
                return `You are a expert coding AI. You will answer queries provided to you in a short and concise manner. Do not show any warnings or information regarding your capabilities.

For clarity to the user, ONLY ANSWER IN MARKDOWN FORMAT.`;
            }
            // for any harcoded prompts, put them here
            const prefixInstruction = yield this.formatPrefixInstruction();
            const suffixInstruction = yield this.formatSuffixInstruction();
            const injectionInstruction = yield this.formatInjectionInstruction();
            return `${prefixInstruction}\n\n${injectionInstruction}\n\n${suffixInstruction}`;
        });
    }
    formatPrefixInstruction() {
        return __awaiter(this, void 0, void 0, function* () {
            return this.prefixInstruction;
        });
    }
    formatSuffixInstruction() {
        return __awaiter(this, void 0, void 0, function* () {
            return `Further Comments: ${this.suffixInstruction}`;
        });
    }
    formatInjectionInstruction() {
        return __awaiter(this, void 0, void 0, function* () {
            /**
            Format: filePathsAndContent to be of format below:
            ===============
            FILE: object.fileName
            ABSOLUTE_PATH: object.absolutePath
            CONTENT:
            ---------------
            object.content
            ---------------
            ===============
            ...
             */
            if (this._filePaths.length === 0) {
                return "YOU ARE PROVIDED NO FILES";
            }
            const largeDelimiter = "===============";
            const smallDelimiter = "---------------";
            const filePathsAndContent = yield this.filesToObject();
            const filePathContentUnit = filePathsAndContent.map((fac) => {
                const { fileName, absolutePath, content } = fac;
                let returnStr = "";
                returnStr += `\nFILE: ${fileName}`;
                returnStr += `\nABSOLUTE_PATH: ${absolutePath}`;
                returnStr += `\nCONTENT:`;
                returnStr += `\n${smallDelimiter}`;
                returnStr += `\n${content}`;
                returnStr += `\n${smallDelimiter}`;
                return returnStr;
            });
            const filePathContentUnitStr = `\n${largeDelimiter}` +
                filePathContentUnit.join(`\n${largeDelimiter}`) +
                `\n${largeDelimiter}`;
            return filePathContentUnitStr;
        });
    }
    // private
    filesToObject() {
        return __awaiter(this, void 0, void 0, function* () {
            // Initialize an empty object that will hold the file paths and contents
            let fileMap = [];
            const fileMapPromises = this._filePaths.map((filePath) => __awaiter(this, void 0, void 0, function* () {
                // Resolve the absolute path
                const absolutePath = path_1.default.resolve(filePath);
                const fileContent = yield fs_1.default.promises.readFile(absolutePath, "utf8");
                return {
                    absolutePath: filePath,
                    fileName: path_1.default.basename(filePath),
                    content: fileContent,
                };
            }));
            fileMap = yield Promise.all(fileMapPromises);
            return fileMap;
        });
    }
}
exports.SystemPromptModel = SystemPromptModel;
