"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TemplateProcessor = void 0;
const tslib_1 = require("tslib");
const replace_in_file_1 = require("replace-in-file");
const fs = (0, tslib_1.__importStar)(require("fs"));
const path_1 = require("path");
class TemplateProcessor {
    constructor(templateData, workspace) {
        this.templateData = templateData;
        this.workspace = workspace;
    }
    async processTemplateUpdate(values) {
        if (this.templateData.templateFields.length != values.length)
            throw new Error("Template values length must match field length");
        // Add trimmed name into replacement template
        values = this.insertTrimmedName(values);
        // TODO: Add src & JS files?
        const results = await this.replaceInFiles(values, ["*.xml", "*.html"]);
        let replacements = results.reduce((count, currentValue) => {
            return count + (currentValue.hasChanged ? 1 : 0);
        }, 0);
        if (!replacements) {
            console.log("Nothing was updated in the project");
            return;
        }
        for (let i = 0; i < values.length; i++) {
            this.templateData.templateFields[i].value = values[i];
        }
        fs.writeFileSync((0, path_1.join)(this.workspace, "tstemplate.json"), JSON.stringify(this.templateData, null, "\t"));
    }
    async updateHardHat(file) {
        let hardhatRelPath = { directory: (0, path_1.join)(this.workspace, file) };
        this.templateData.hardhat?.push(hardhatRelPath);
        fs.writeFileSync((0, path_1.join)(this.workspace, "tstemplate.json"), JSON.stringify(this.templateData, null, "\t"));
    }
    getHardHatDirectory() {
        var dir = "";
        for (let element of this.templateData.hardhat) {
            if ('directory' in element) {
                dir = element.directory;
                break;
            }
        }
        return dir;
    }
    async replaceInFiles(values, fileNames) {
        let filesForReplace = [];
        for (let file of fileNames) {
            filesForReplace.push((0, path_1.join)(this.workspace, file));
        }
        return await (0, replace_in_file_1.replaceInFile)({
            files: filesForReplace,
            allowEmptyPaths: true,
            from: this.templateData.templateFields.map((field) => {
                if (field.value) {
                    let value = this.escapeRegExp(field.value);
                    return new RegExp(field.updatePrefix ?
                        "(" + this.escapeRegExp(field.updatePrefix) + ")" + value :
                        value, 'g');
                }
                return new RegExp("\\\$tst\\\{" + field.token + "\\\}", 'g');
            }),
            to: values.map((value, index) => {
                let template = this.templateData.templateFields[index];
                if (template.value && template.updatePrefix)
                    return "$1" + value;
                return value;
            })
        });
    }
    getValuesFromTSTemplate() {
        let values = [];
        let newTemplateFields = [];
        for (let templateField of this.templateData.templateFields) {
            let value = templateField.value;
            values.push(value);
            let thisTemplateField = { name: templateField.name, token: templateField.token, prompt: templateField.prompt };
            if ('updatePrefix' in templateField) {
                thisTemplateField.updatePrefix = templateField.updatePrefix;
            }
            if ('options' in templateField) {
                thisTemplateField.options = templateField.options;
            }
            newTemplateFields.push(thisTemplateField);
        }
        this.templateData.templateFields = newTemplateFields;
        return values;
    }
    insertTrimmedName(values) {
        const trimIndex = this.templateData.templateFields.findIndex((element) => element.token === 'TOKENSCRIPT_TRIM');
        const nameIndex = this.templateData.templateFields.findIndex((element) => element.token === 'TOKENSCRIPT_NAME');
        //If trim name exists (running a re-create) remove it first case the TokenScript name changed
        if (trimIndex >= 0) {
            this.templateData.templateFields.splice(trimIndex, 1);
            values.splice(trimIndex, 1);
        }
        if (nameIndex >= 0) {
            const trimVal = values[nameIndex].replace(/\s/g, "-");
            let trimEntry = { name: 'Trimmed Name', token: 'TOKENSCRIPT_TRIM', prompt: '' };
            this.templateData.templateFields.push(trimEntry);
            values.push(trimVal);
        }
        return values;
    }
    escapeRegExp(string) {
        return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
    }
}
exports.TemplateProcessor = TemplateProcessor;
