"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerExtension = exports.Module = exports.defineModules = void 0;
var tslib_1 = require("tslib");
/* eslint-disable no-use-before-define */
/* eslint-disable @typescript-eslint/no-use-before-define */
var path = tslib_1.__importStar(require("path"));
var util_1 = require("./util");
var core_module_1 = require("./core_module");
function defineModules(allModules, opts) {
    (0, core_module_1.init)(opts.runtime);
    var definedModules = {};
    opts.runtime[opts.defineFuncName] = function (id, factory) {
        definedModules[id].factory = factory;
    };
    Object.entries(allModules).map(function (_a) {
        var _b = tslib_1.__read(_a, 2), id = _b[0], modData = _b[1];
        var mod = new Module(id, modData.url);
        definedModules[id] = mod;
        try {
            mod.defineModule(modData.code, opts.defineFuncName, opts.runtime);
        }
        catch (e) {
            opts.onError(e);
        }
    });
    Object.entries(definedModules).map(function (_a) {
        var _b = tslib_1.__read(_a, 2), id = _b[0], mod = _b[1];
        Object.entries(allModules[id].requires).map(function (_a) {
            var _b = tslib_1.__read(_a, 2), requirePath = _b[0], resolvedPath = _b[1];
            mod.dependencies[requirePath] = definedModules[resolvedPath];
        });
    });
    return definedModules;
}
exports.defineModules = defineModules;
// https://nodejs.org/api/modules.html#modules_the_module_object
var Module = /** @class */ (function () {
    function Module(id, url) {
        var _this = this;
        this.dependencies = {};
        this.require = function (path) {
            var dep = _this.dependencies[path];
            if (dep) {
                return dep.execute();
            }
            console.warn("Dependeny ".concat(path, " not loaded properly for ").concat(_this.id));
        };
        this.id = id;
        this.url = url;
    }
    Module.prototype.execute = function () {
        if (this.exports) {
            // console.warn('Using cached exports for ' + self.id)
            return this.exports;
        }
        this.exports = {};
        this.factory.call(this.exports, this.require, this.exports, this);
        return this.exports;
    };
    /**
     * Register the module
     */
    Module.prototype.defineModule = function (srcCode, defineFuncName, runtime) {
        var id = this.id;
        var ext = path.extname(id).substr(1);
        var source = srcCode;
        if (loaders[ext]) {
            source = loaders[ext](source);
        }
        var code = "".concat(defineFuncName, "(\"").concat(id, "\", function(require, exports, module) {\n").concat(source, "\n})//# sourceURL=").concat(id);
        if (runtime.document) {
            (0, util_1.evalCode)(code, runtime.document);
        }
        else {
            console.warn('script runtime error, runtime do not has document.');
        }
        if (typeof this.factory !== 'function') {
            throw new Error("Lowcode syntax error of module ".concat(this.url));
        }
    };
    return Module;
}());
exports.Module = Module;
var loaders = {
    json: function (src) {
        return "module.exports=".concat(src);
    },
    css: textLoader,
    txt: textLoader,
};
function registerExtension(ext, transform) {
    if (loaders[ext]) {
        console.error("Duplicate transform for ".concat(ext));
        return;
    }
    loaders[ext] = transform;
}
exports.registerExtension = registerExtension;
function textLoader(src) {
    return "module.exports=".concat(JSON.stringify(src));
}
//# sourceMappingURL=module.js.map