"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseMinipAppAlias = exports.getMinipAppConfig = exports.getMinipProjectConfig = exports.traverse = exports.createQueryDependsMap = exports.createQueryDepends = exports.cleanUpSurroundPath = exports.resolveDependRouter = exports.resolveAlias = exports.resolveRouter = void 0;
var fs_1 = __importDefault(require("fs"));
var path_1 = __importDefault(require("path"));
var resolveRouter = function (router, options) {
    var _a = options.alias, alias = _a === void 0 ? {} : _a, _b = options.extensions, extensions = _b === void 0 ? [] : _b;
    return resolveExtension((0, exports.resolveAlias)(router, alias), extensions);
};
exports.resolveRouter = resolveRouter;
var useAlias = function (router, map) {
    return Object.keys(map).some(function (a) { return router.startsWith(a); });
};
var resolveAlias = function (router, map) {
    var alias = Object.keys(map).find(function (a) { return router.startsWith(a); });
    if (alias) {
        router = path_1.default.join(map[alias], router.substring(alias.length));
    }
    return router;
};
exports.resolveAlias = resolveAlias;
var resolveIndex = function (router) {
    if (fs_1.default.existsSync(router) && fs_1.default.statSync(router).isDirectory()) {
        router = path_1.default.join(router, 'index');
    }
    return router;
};
var resolveDependRouter = function (sourceFile, router, options) {
    var _a = options.alias, alias = _a === void 0 ? {} : _a, _b = options.extensions, extensions = _b === void 0 ? [] : _b;
    if (useAlias(router, alias)) {
        return (0, exports.resolveRouter)(router, options);
    }
    else {
        return resolveExtension(path_1.default.resolve(sourceFile, router), extensions);
    }
};
exports.resolveDependRouter = resolveDependRouter;
var resolveExtension = function (file, exts) {
    file = resolveIndex(file);
    if (!fs_1.default.existsSync(file) || !fs_1.default.statSync(file).isFile()) {
        var ext = exts.find(function (x) { return fs_1.default.existsSync("".concat(file).concat(x)); });
        if (ext) {
            return "".concat(file).concat(ext);
        }
    }
    return file;
};
var cleanUpSurroundPath = function (p) {
    p = p.replace(/^\s+|\s+$/g, '');
    var h = p.charAt(0) || '', t = p.charAt(p.length - 1) || '';
    if ((h === '"' && t === '"') || (h === "'" && t === "'")) {
        return p.substring(1, p.length - 1);
    }
    else if (h === '(' && t === ')') {
        return (0, exports.cleanUpSurroundPath)(p.substring(1, p.length - 1));
    }
    else {
        return p;
    }
};
exports.cleanUpSurroundPath = cleanUpSurroundPath;
var readCode = function (file) {
    if (fs_1.default.existsSync(file) && fs_1.default.statSync(file).isFile()) {
        return fs_1.default.readFileSync(file, 'utf-8');
    }
    return '';
};
var createQueryDepends = function (queryRelations) {
    var qd = function (file, options, result) {
        if (result.includes(file)) {
            return;
        }
        result.push(file);
        var code = readCode(file);
        var depends = queryRelations(code, file);
        var sourcePath = path_1.default.dirname(file);
        depends.forEach(function (relPath) {
            var fullpath = (0, exports.resolveDependRouter)(sourcePath, relPath, options);
            qd(fullpath, options, result);
        });
    };
    return function (router, options) {
        if (options === void 0) { options = {}; }
        var files = [];
        var file = (0, exports.resolveRouter)(router, options);
        qd(file, options, files);
        return files;
    };
};
exports.createQueryDepends = createQueryDepends;
var parseDependItem = function (file, root) {
    var routerFile = path_1.default.relative(root, file);
    var type = path_1.default.extname(file);
    var router = routerFile.substring(0, routerFile.length - type.length);
    var exists = fs_1.default.existsSync(file) && fs_1.default.statSync(file).isFile();
    return {
        file: file,
        exists: exists,
        router: router,
        type: type,
        depends: []
    };
};
var createQueryDependsMap = function (queryRelations) {
    var qd = function (file, options, result, parent) {
        if (result.includes(file)) {
            return;
        }
        result.push(file);
        var _a = options.alias, _b = _a === void 0 ? {} : _a, _c = _b["/"], root = _c === void 0 ? '' : _c;
        var item = parseDependItem(file, root);
        parent.depends.push(item);
        var code = readCode(file);
        var depends = queryRelations(code, file);
        var sourcePath = path_1.default.dirname(file);
        depends.forEach(function (relPath) {
            var fullpath = (0, exports.resolveDependRouter)(sourcePath, relPath, options);
            qd(fullpath, options, result, item);
        });
    };
    return function (router, options) {
        if (options === void 0) { options = {}; }
        var files = [];
        var file = (0, exports.resolveRouter)(router, options);
        var _a = options.alias, _b = _a === void 0 ? {} : _a, _c = _b["/"], root = _c === void 0 ? '' : _c;
        var current = {
            file: root,
            exists: false,
            router: '/',
            type: 'root',
            depends: []
        };
        qd(file, options, files, current);
        return current;
    };
};
exports.createQueryDependsMap = createQueryDependsMap;
var calTraverseStatus = function (idx, len) {
    if (len <= 1) {
        return 3;
    }
    else {
        return idx >= len - 1 ? 2 : idx === 0 ? 0 : 1;
    }
};
var _traverse = function (item, callback, depth, status) {
    callback(item, depth, status);
    if (Array.isArray(item.depends) && item.depends.length > 0) {
        var len_1 = item.depends.length;
        item.depends.forEach(function (it, idx) {
            _traverse(it, callback, depth + 1, calTraverseStatus(idx, len_1));
        });
    }
};
var traverse = function (item, callback) {
    if (item.type === 'root') {
        if (Array.isArray(item.depends) && item.depends.length > 0) {
            var len_2 = item.depends.length;
            item.depends.forEach(function (it, idx) {
                _traverse(it, callback, 0, calTraverseStatus(idx, len_2));
            });
        }
    }
    else {
        _traverse(item, callback, 0, 3);
    }
};
exports.traverse = traverse;
var getMinipProjectConfig = function (rootDir) {
    var dir = path_1.default.resolve(process.cwd(), rootDir);
    if (!fs_1.default.existsSync(dir)) {
        throw new Error("[getMinipProjectConfig] dir '".concat(dir, "' is not exists."));
    }
    if (!fs_1.default.statSync(dir).isDirectory()) {
        throw new Error("[getMinipProjectConfig] dir '".concat(dir, "' is not a directory."));
    }
    var projPath = path_1.default.join(dir, 'project.config.json');
    if (!fs_1.default.existsSync(projPath) || !fs_1.default.statSync(projPath).isFile()) {
        throw new Error("[getMinipProjectConfig] config file '".concat(projPath, "' is not exists."));
    }
    var code = fs_1.default.readFileSync(projPath, 'utf-8');
    try {
        var conf = JSON.parse(code);
        return conf;
    }
    catch (err) {
        throw new Error("[getMinipProjectConfig] parse config file failed:\n".concat(err));
    }
};
exports.getMinipProjectConfig = getMinipProjectConfig;
var getMinipAppConfig = function (rootDir) {
    var _a = (0, exports.getMinipProjectConfig)(rootDir).miniprogramRoot, miniprogramRoot = _a === void 0 ? '' : _a;
    var dir = path_1.default.resolve(process.cwd(), rootDir);
    var root = path_1.default.resolve(dir, miniprogramRoot);
    var appFile = path_1.default.join(root, 'app.json');
    if (!fs_1.default.existsSync(appFile) || !fs_1.default.statSync(appFile).isFile()) {
        throw new Error("[getMinipApp] app.json '".concat(appFile, "' is not exists."));
    }
    var code = fs_1.default.readFileSync(appFile, 'utf-8');
    try {
        var app = JSON.parse(code);
        return { root: root, app: app };
    }
    catch (err) {
        throw new Error("[getMinipApp] parse app.json failed:\n".concat(err));
    }
};
exports.getMinipAppConfig = getMinipAppConfig;
var parseMinipAppAlias = function (rootDir) {
    var dir = path_1.default.resolve(process.cwd(), rootDir);
    var appConfig = (0, exports.getMinipAppConfig)(rootDir);
    var root = appConfig.root, _a = appConfig.app.resolveAlias, resolveAlias = _a === void 0 ? {} : _a;
    var alias = { '/': root };
    Object.entries(resolveAlias).forEach(function (_a) {
        var key = _a[0], val = _a[1];
        alias[key.replace(/\*+$/, '')] = path_1.default.join(root, val.replace(/\*+$/, '').replace(/^\//, ''));
    });
    return alias;
};
exports.parseMinipAppAlias = parseMinipAppAlias;
