"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.BuildProcessor = void 0;
const tslib_1 = require("tslib");
const fs_1 = (0, tslib_1.__importDefault)(require("fs"));
const xmldom_1 = require("@xmldom/xmldom");
const prepareOutputDirectory_1 = require("./steps/prepareOutputDirectory");
const canonicalizeXml_1 = require("./steps/canonicalizeXml");
const validateXml_1 = require("./steps/validateXml");
const inlineIncludes_1 = require("./steps/inlineIncludes");
const jsdom_1 = require("jsdom");
class BuildProcessor {
    constructor(workspace, cli, statusCallback) {
        this.workspace = workspace;
        this.cli = cli;
        this.statusCallback = statusCallback;
        this.xmlString = null;
        this.xmlDoc = null;
    }
    updateStatus(status) {
        this.statusCallback(status);
    }
    async build() {
        for (let BuildStep of BuildProcessor.BUILD_STEPS) {
            let buildStep = new BuildStep(this);
            await new Promise(resolve => setTimeout(resolve, 500));
            await buildStep.runBuildStep();
        }
    }
    async validate() {
        const index = BuildProcessor.BUILD_STEPS.indexOf(validateXml_1.ValidateXml);
        const validator = new BuildProcessor.BUILD_STEPS[index](this);
        await validator.runBuildStep();
    }
    getXmlString() {
        if (!this.xmlString) {
            this.xmlString = fs_1.default.readFileSync(this.workspace + BuildProcessor.SRC_XML_FILE, 'utf-8');
        }
        return this.xmlString;
    }
    getXmlDoc() {
        if (!this.xmlDoc) {
            this.xmlDoc = this.parseXml(this.getXmlString());
        }
        return this.xmlDoc;
    }
    setXmlString(xml) {
        this.xmlDoc = null;
        this.xmlString = xml;
        this.saveXmlOutput();
    }
    setXmlDoc(xmlDoc) {
        this.xmlDoc = xmlDoc;
        this.xmlString = new xmldom_1.XMLSerializer().serializeToString(this.xmlDoc);
        //this.xmlString = serialize(this.xmlDoc, { requireWellFormed: false });
        //this.xmlString = this.xmlDoc.documentElement.outerHTML;
        this.saveXmlOutput();
        // TODO: Fix: For some reason validation fails in some cases unless the XML string is reloaded from the disk.
        this.xmlString = null;
    }
    getOutputXmlPath() {
        return this.workspace + BuildProcessor.OUTPUT_DIR + "/tokenscript.tsml";
    }
    saveXmlOutput() {
        fs_1.default.writeFileSync(this.getOutputXmlPath(), this.xmlString);
    }
    parseXml(xmlString, type = "text/xml") {
        const dom = new jsdom_1.JSDOM("");
        const DOMParser = dom.window.DOMParser;
        const parser = new DOMParser;
        return parser.parseFromString(xmlString, type);
        //this.xmlDoc = new DOMParser().parseFromString(this.getXmlString(), 'text/xml');
    }
}
exports.BuildProcessor = BuildProcessor;
BuildProcessor.BUILD_STEPS = [
    prepareOutputDirectory_1.PrepareOutputDirectory,
    canonicalizeXml_1.CanonicalizeXml,
    inlineIncludes_1.InlineIncludes,
    validateXml_1.ValidateXml
];
BuildProcessor.OUTPUT_DIR = "/out";
BuildProcessor.SRC_XML_FILE = "/tokenscript.xml";
