"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.getModules = getModules;
exports.getModuleGit = getModuleGit;
exports.addPack = addPack;
exports.unaddPack = unaddPack;
exports.installModules = installModules;
exports.uninstallModule = uninstallModule;
exports.unInstallModules = unInstallModules;
exports.getResConfig = getResConfig;
exports.getModuleInfo = getModuleInfo;
const git_1 = __importDefault(require("../git"));
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const node_fs_1 = __importDefault(require("node:fs"));
const promises_1 = __importDefault(require("node:fs/promises"));
const utils = __importStar(require("./../utils"));
const commander_1 = require("../commander");
const index_js_1 = __importDefault(require("../lang/index.js"));
const index_js_2 = __importDefault(require("../loger/index.js"));
const gitVerifyReg = /(https?:\/\/[^\s\/]+\/[^\s\/]+\/[^\s]+(?:\.git)?|(?:git@|[\w.-]+@)[\w.-]+:[^\s]+(?:\.git)?)/;
// 缓存
const cache = new Map();
let moduleDirname = "";
let gitRepo = "";
let cacheList = null;
/**
 * 版本号转数组
 */
function versionToArray(v) {
    return String(v || '0.0.0').trim()
        .split('.')
        .slice(0, 3)
        .map((n) => parseInt(n, 10) || 0);
}
/**
 * 比较版本号
 */
function compareVersion(a, b) {
    const A = versionToArray(a);
    const B = versionToArray(b);
    for (let i = 0; i < 3; i++) {
        const a = A[i];
        const b = B[i];
        if (a === undefined || b === undefined)
            continue;
        if (a !== b)
            return a > b ? 1 : -1;
    }
    return 0;
}
class ModuleDir {
    static curreny;
    static get() {
        if (ModuleDir.curreny)
            return ModuleDir.curreny;
        const d = node_path_1.default.join(node_os_1.default.homedir(), ".cache/mbler/.moduleDir.db");
        let content;
        try {
            content = node_fs_1.default.readFileSync(d, "utf-8").toString();
        }
        catch {
            content = node_path_1.default.join(__dirname, "../modules");
        }
        ModuleDir.curreny = content;
        return content;
    }
    static async set(newDir) {
        if (!ModuleDir.curreny)
            ModuleDir.get();
        if (!await utils.FileExsit(newDir))
            throw new TypeError("[module dir set]: dir isn't exsit");
        await promises_1.default.cp(ModuleDir.curreny, newDir, {
            recursive: true,
            force: true
        });
        const userSelect = await commander_1.Input.select("已将模块复制至目标文件夹，是否删除旧文件夹？ ", ["Y", "N"]);
        if (userSelect == "Y") {
            await promises_1.default.rm(ModuleDir.curreny, {
                recursive: true
            });
        }
        else if (userSelect !== "N") {
            throw new Error("[moduleDir set]: ??? your select is sb");
        }
        ModuleDir.curreny = newDir;
        return true;
    }
}
/**
 * 获取模块列表
 */
async function getModules(dirname) {
    const contentsPath = node_path_1.default.join(dirname, './lib/modules/contents.json');
    const data = JSON.parse((await promises_1.default.readFile(contentsPath, "utf-8")).toString());
    return data.map((item) => item.name);
}
/**
 * 根据名称获取模块 Git URL
 */
async function getModuleGit(dirname, packName) {
    const contentsPath = node_path_1.default.join(dirname, './lib/modules/contents.json');
    const data = JSON.parse((await promises_1.default.readFile(contentsPath, "utf-8")).toString());
    const moduleItem = data.find((item) => item.name === packName);
    return moduleItem?.git || null;
}
/**
 * 添加包到依赖
 */
async function addPack(packName, dirname_, workDir) {
    const dirname = dirname_;
    const modules = await getModuleInfo(dirname);
    try {
        if (!modules.getAll().includes(packName)) {
            throw new Error(index_js_1.default.invalidDes);
        }
        if (!await utils.FileExsit(workDir)) {
            throw new Error(index_js_1.default.config_invalid);
        }
        const packageObj = await utils.GetData(workDir);
        const gitUrl = await getModuleGit(dirname, packName);
        if (!gitUrl) {
            throw new Error(`${packName} : ${index_js_1.default.noGitRepo}`);
        }
        if (!packageObj?.script?.dependencies) {
            packageObj.script.dependencies = {};
        }
        packageObj.script.dependencies[packName] = gitUrl;
        const updatedContent = JSON.stringify(packageObj, null, 2);
        await promises_1.default.writeFile(node_path_1.default.join(workDir, node_path_1.default.basename(utils.config.PackageFile)), updatedContent);
    }
    catch (err) {
        index_js_2.default.e('add', `ERR- ${err.stack}`);
    }
}
/**
 * 从包依赖中移除
 */
async function unaddPack(packName, dirname_, workDir) {
    const dirname = dirname_;
    const modules = await getModuleInfo(dirname);
    try {
        if (!modules.getAll().includes(packName)) {
            throw new Error(index_js_1.default.invalidDes);
        }
        if (!await utils.FileExsit(workDir)) {
            throw new Error(index_js_1.default.config_invalid);
        }
        const packageObj = await utils.GetData(workDir);
        if (packageObj?.script?.dependencies?.[packName]) {
            delete packageObj.script.dependencies[packName];
            const updatedContent = JSON.stringify(packageObj, null, 2);
            await promises_1.default.writeFile(node_path_1.default.join(workDir, node_path_1.default.basename(utils.config.PackageFile)), updatedContent);
        }
    }
    catch (err) {
        index_js_2.default.e('unadd', `ERR- ${err.stack}`);
    }
}
/**
 * 安装全局模块
 */
async function installGlobal(two, ab = true) {
    gitRepo = two;
    const tempDir = node_path_1.default.join(node_os_1.default.tmpdir(), `mbler-${Date.now()}`);
    try {
        if (two === "inner")
            return true;
        if (!two)
            throw new Error(index_js_1.default.noGitRepo);
        if (!gitVerifyReg.test(two))
            return await fileInstall(two);
        await git_1.default.clone(two, tempDir);
        try {
            const pack = await utils.GetData(tempDir);
            await addMod(pack, { dir: tempDir });
        }
        catch {
            throw new Error(index_js_1.default.installGit.NoPackage);
        }
        return true;
    }
    catch (err) {
        index_js_2.default.e('INSTALL', err.message);
        return false;
    }
    finally {
        await promises_1.default.rm(tempDir, { recursive: true, force: true });
    }
}
/**
 * 从本地文件安装模块
 */
async function fileInstall(localPath) {
    const dir = node_path_1.default.join(moduleDirname, localPath);
    const fileStat = await promises_1.default.stat(dir);
    if (fileStat.isFile())
        throw new Error('No Folder');
    const pack = await utils.GetData(dir);
    await addMod(pack, { dir: dir });
    return true;
}
/**
 * 比较模块版本
 */
async function compareModuleVersion(aD, bD) {
    const A = versionToArray((await utils.GetData(aD)).version);
    const B = versionToArray((await utils.GetData(bD)).version);
    for (let i = 0; i < 3; i++) {
        const a = A[i];
        const b = B[i];
        if (a === undefined || b === undefined)
            continue;
        if (a !== b)
            return a > b ? 1 : -1;
    }
    return 0;
}
/**
 * 添加模块到系统
 */
async function addMod(pack, tempMod, b = true) {
    index_js_2.default.i('INSTALL', `${index_js_1.default.installGit.SetContent} ${pack.name}`);
    const soListDir = node_path_1.default.join(moduleDirname, './lib/modules/contents.json');
    const soList = JSON.parse((await promises_1.default.readFile(soListDir)).toString());
    const installModPack = JSON.parse(await promises_1.default.readFile(node_path_1.default.join(tempMod.dir, "mbler.config.json"), "utf-8"));
    const innerDef = cache.get('innerDef');
    if (innerDef?.includes(pack.name)) {
        return index_js_2.default.e('INSTALL', index_js_1.default.SameDes);
    }
    const za = soList.find((item) => item.name === pack.name || item.git === gitRepo);
    const versionCompare = za ? await compareModuleVersion(tempMod.dir, node_path_1.default.join(moduleDirname, "lib/modules", za.name)) : 1;
    if (za && versionCompare <= 0 && b) {
        if (await utils.input(index_js_1.default.installGit.HadBeen) !== 'Y')
            return;
    }
    soList.push({ name: pack.name, git: gitRepo });
    await promises_1.default.writeFile(soListDir, JSON.stringify(soList));
    await utils.copy(tempMod.dir, node_path_1.default.join(moduleDirname, './lib/modules/', pack.name));
}
/**
 * 安装模块
 */
async function installModules(Dirname, workDir) {
    try {
        moduleDirname = Dirname;
        cache.set('innerDef', JSON.parse(await promises_1.default.readFile(node_path_1.default.join(moduleDirname, './lib/modules/innerDef.json'), "utf-8")));
        const p = await utils.GetData(workDir);
        const Mods = process.argv.slice(3);
        const dependencies = p.script?.dependencies || {};
        for (const i of Object.values(dependencies)) {
            if (!i)
                continue;
            await installGlobal(i, false);
        }
        for (const i of Mods) {
            if (!i)
                continue;
            await installGlobal(i, true);
        }
    }
    catch (err) {
        index_js_2.default.e("INSTALL", `ERR in 'InstallModules' Func\nMessage: ${err.message}\nstack : ${err.stack}`);
    }
    finally {
        index_js_2.default.i('INSTALL', index_js_1.default.installGit.InstallFinally);
    }
}
/**
 * 卸载单个模块
 */
async function uninstallModule(packName, dirname) {
    try {
        moduleDirname = dirname;
        cache.set('innerDef', JSON.parse(await promises_1.default.readFile(node_path_1.default.join(moduleDirname, './lib/modules/innerDef.json'), "utf-8")));
        return await uninstallGlobalInternal(packName);
    }
    catch (err) {
        index_js_2.default.e('uninstall', err.message);
        return false;
    }
}
/**
 * 卸载模块
 */
async function unInstallModules(Dirname, workDir) {
    try {
        moduleDirname = Dirname;
        cache.set('innerDef', JSON.parse(await promises_1.default.readFile(node_path_1.default.join(moduleDirname, './lib/modules/innerDef.json'), "utf-8")));
        const p = await utils.GetData(workDir);
        const Mods = process.argv.slice(3);
        const dependencies = p.script?.dependencies || {};
        for (const i of Object.keys(dependencies)) {
            if (!i)
                continue;
            await uninstallGlobalInternal(i);
        }
        for (const i of Mods) {
            if (!i)
                continue;
            await uninstallGlobalInternal(i);
        }
    }
    catch (err) {
        index_js_2.default.e("UNINSTALL", `ERR in 'unInstallModules' Func\nMessage: ${err.message}\nstack : ${err.stack}`);
    }
    finally {
        index_js_2.default.i('UNINSTALL', index_js_1.default.uninstallFinally);
    }
}
async function uninstallGlobalInternal(moduleName) {
    try {
        const contentsPath = node_path_1.default.join(moduleDirname, './lib/modules/contents.json');
        const contents = JSON.parse((await promises_1.default.readFile(contentsPath, "utf-8")).toString());
        const moduleIndex = contents.findIndex((item) => item.name === moduleName);
        if (moduleIndex === -1) {
            index_js_2.default.e('UNINSTALL', `${index_js_1.default.moduleNotFound}: ${moduleName}`);
            return false;
        }
        const moduleItem = contents[moduleIndex];
        const innerDef = cache.get('innerDef');
        if (innerDef?.includes(moduleName)) {
            index_js_2.default.e('UNINSTALL', index_js_1.default.CannotDeleteInner);
            return false;
        }
        contents.splice(moduleIndex, 1);
        await promises_1.default.writeFile(contentsPath, JSON.stringify(contents, null, 2));
        const modulePath = node_path_1.default.join(moduleDirname, './lib/modules/', moduleName);
        await promises_1.default.rm(modulePath, { recursive: true, force: true });
        index_js_2.default.i('UNINSTALL', `${index_js_1.default.uninstallSuccess}: ${moduleItem.name}`);
        return true;
    }
    catch (err) {
        index_js_2.default.e('UNINSTALL', err.message);
        return false;
    }
    async function uninstallGlobal(moduleName) {
        try {
            const contentsPath = node_path_1.default.join(moduleDirname, './lib/modules/contents.json');
            const contents = JSON.parse((await promises_1.default.readFile(contentsPath, "utf-8")).toString());
            const moduleIndex = contents.findIndex((item) => item.name === moduleName);
            if (moduleIndex === -1) {
                index_js_2.default.e('UNINSTALL', `${index_js_1.default.moduleNotFound}: ${moduleName}`);
                return false;
            }
            const moduleItem = contents[moduleIndex];
            const innerDef = cache.get('innerDef');
            if (innerDef?.includes(moduleName)) {
                index_js_2.default.e('UNINSTALL', index_js_1.default.CannotDeleteInner);
                return false;
            }
            contents.splice(moduleIndex, 1);
            await promises_1.default.writeFile(contentsPath, JSON.stringify(contents, null, 2));
            const modulePath = node_path_1.default.join(moduleDirname, './lib/modules/', moduleName);
            await promises_1.default.rm(modulePath, { recursive: true, force: true });
            index_js_2.default.i('UNINSTALL', `${index_js_1.default.uninstallSuccess}: ${moduleItem.name}`);
            return true;
        }
        catch (err) {
            index_js_2.default.e('UNINSTALL', err.message);
            return false;
        }
    }
}
/**
 * 获取资源配置
 */
async function getResConfig(dirname) {
    cache.set('Mod', JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dirname, './lib/modules/contents.json'), "utf-8")));
    cache.set('innerDef', JSON.parse(await promises_1.default.readFile(node_path_1.default.join(dirname, './lib/modules/innerDef.json'), "utf-8")));
    return cache;
}
class ModulePath {
    dir;
    cache;
    constructor(dirname) {
        this.dir = dirname;
        this.cache = [];
    }
    async start() {
        this.cache = await this.#loadContents();
    }
    getGit(name) {
        for (const item of this.cache) {
            if (item.name === name)
                return item.git;
        }
        return null;
    }
    getAll() {
        if (cacheList)
            return cacheList;
        cacheList = this.cache.map(item => item.name);
        return cacheList;
    }
    async #loadContents() {
        const dataPath = node_path_1.default.join(this.dir, 'lib/modules/contents.json');
        try {
            const content = await promises_1.default.readFile(dataPath, 'utf8');
            const data = utils.JSONparse(content);
            return (typeof data === 'object' && data !== null) ? data : [];
        }
        catch (err) {
            console.error('Failed to load contents.json:', err);
            return [];
        }
    }
}
/**
 * 获取模块信息
 */
async function getModuleInfo(dirname) {
    cacheList = null;
    const instance = new ModulePath(dirname);
    await instance.start();
    return instance;
}
class Module {
    static globalModuleDir = ModuleDir.get();
    static async Install(mod) {
        let result = {
            lastTip: "",
            res: false
        };
        let from = mod.git;
        if (mod.git == "inner") {
            from = "git+https://github.com/Ruanhor.git";
        }
        if (from.startsWith("git+")) {
            const moduleDir = node_path_1.default.join(ModuleDir.curreny, mod.name);
            if (await utils.FileExsit(moduleDir)) {
                result.lastTip = "error: [module]: " + mod.name + "exsit";
            }
            const gitUrl = from.replace("git+", "");
            if (!gitVerifyReg.test(gitUrl)) {
                result.lastTip = "error: [clone git]: url isn't format";
                return result;
            }
            await git_1.default.clone(gitUrl, moduleDir);
        }
        if (from.startsWith(""))
            return result;
        return result;
    }
}
exports.default = Module;
