"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.HotPage = void 0;
const Hot_1 = require("./Hot");
const HotStaq_1 = require("./HotStaq");
/**
 * A page to preprocess.
 */
class HotPage {
    constructor(copy) {
        if (copy instanceof HotStaq_1.HotStaq) {
            this.processor = copy;
            this.name = "";
            this.testerName = "HotTesterMochaSelenium";
            this.testerMap = "";
            this.route = "";
            this.components = {};
            this.files = [];
            this.functions = {};
            this.testElements = {};
            this.testPaths = {};
        }
        else {
            this.processor = copy.processor;
            this.name = copy.name || "";
            this.testerName = copy.testerName || "HotTesterMochaSelenium";
            this.testerMap = copy.testerMap || "";
            this.route = copy.route || "";
            this.components = copy.components || {};
            this.files = copy.files || [];
            this.functions = copy.functions || {};
            this.testElements = copy.testElements || {};
            this.testPaths = copy.testPaths || {};
        }
    }
    /**
     * Add a file to process. It's recommend to load the file prior to
     * adding it to a page if it's about to be used.
     */
    addFile(file) {
        return __awaiter(this, void 0, void 0, function* () {
            file.page = this;
            this.files.push(file);
        });
    }
    /**
     * Get the API associated with this page.
     */
    getAPI() {
        return (this.processor.api);
    }
    /**
     * Get the tester API associated with this page.
     */
    getTesterAPI() {
        return (this.processor.testerAPI);
    }
    /**
     * Add all files in the page. Could decrease page loading performance.
     * It's recommend to load the file prior to adding it to a page.
     */
    load(file) {
        return __awaiter(this, void 0, void 0, function* () {
            for (let iIdx = 0; iIdx < this.files.length; iIdx++) {
                let file = this.files[iIdx];
                yield file.load();
            }
        });
    }
    /**
     * Process a page and get the result.
     */
    process() {
        return __awaiter(this, arguments, void 0, function* (args = null) {
            let output = "";
            for (let iIdx = 0; iIdx < this.files.length; iIdx++) {
                let file = this.files[iIdx];
                Hot_1.Hot.Output = "";
                file.page = this;
                output += yield file.process(args);
            }
            return (output);
        });
    }
    /**
     * Add a function to execute later.
     *
     * @returns The new function's name.
     */
    addFunction(name, args, funcBody, isAsync = false) {
        if (name == null)
            name = "__func" + Object.keys(this.functions).length;
        let argsStr = "";
        let asyncStr = "";
        if (isAsync === true)
            asyncStr = "async ";
        for (let iIdx = 0; iIdx < args.length; iIdx++) {
            const arg = args[iIdx];
            let comma = ",";
            if (iIdx == args.length - 1)
                comma = "";
            argsStr += `${arg}${comma}`;
        }
        this.functions[name] = new Function(`return (${asyncStr}(${argsStr}) => { ${funcBody} }).apply (this, arguments);`);
        return (name);
    }
    /**
     * Calls a function that's been stored and returns the result.
     */
    callFunction(thisObj, name, args) {
        let func = this.functions[name];
        if (func == null)
            throw new Error(`Function ${name} does not exist!`);
        return (func.apply(thisObj, args));
    }
    /**
     * Calls an async function that's been stored and returns the result.
     */
    callAsyncFunction(thisObj, name, args) {
        return __awaiter(this, void 0, void 0, function* () {
            let func = this.functions[name];
            if (func == null)
                throw new Error(`Function ${name} does not exist!`);
            return (func.apply(thisObj, args));
        });
    }
    /**
     * Add a test element.
     */
    addTestElement(elm) {
        if (this.testElements[elm.name] != null)
            throw new Error(`Test element ${elm.name} already exists!`);
        this.testElements[elm.name] = elm;
    }
    /**
     * Get a test element.
     */
    getTestElement(name) {
        if (this.testElements[name] == null)
            throw new Error(`Test element ${name} doest not exist!`);
        return (this.testElements[name]);
    }
    /**
     * Create a test path.
     */
    createTestPath(pathName, driverFunc) {
        if (this.testPaths[pathName] != null)
            throw new Error(`Test path ${pathName} already exists!`);
        this.testPaths[pathName] = driverFunc;
    }
}
exports.HotPage = HotPage;
//# sourceMappingURL=HotPage.js.map