"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 };
};
const index_js_1 = __importDefault(require("./../uuid/index.js"));
const promises_1 = __importDefault(require("fs/promises"));
const utils = __importStar(require("./../utils/index.js"));
const path_1 = __importDefault(require("path"));
const index_js_2 = __importDefault(require("./../git/index.js"));
const child_process_1 = require("child_process");
const index_js_3 = __importDefault(require("./../runTemp/index.js"));
const securityFile_js_1 = __importDefault(require("./../runTemp/securityFile.js"));
const regex = /(https?:\/\/[^\s\/]+\/[^\s\/]+\/[^\s]+(?:\.git)?|(?:git@|[\w.-]+@)[\w.-]+:[^\s]+(?:\.git)?)/;
const npmStart = "npm:";
let dirname = '';
async function Load(cacheDir, workDir) {
    const main = JSON.parse(await promises_1.default.readFile(path_1.default.join(cacheDir, "package.json"), {
        encoding: "utf-8"
    })).main;
    const MblerConfig = JSON.parse(await promises_1.default.readFile(path_1.default.join(cacheDir, "mbler.config.json"), {
        encoding: "utf-8"
    }));
    const query = {
        name: MblerConfig.name,
        description: MblerConfig.description,
        version: MblerConfig.version,
        // securityFile提供不能来到上级的文件操作
        setWorkDir: new securityFile_js_1.default(workDir)
    };
    let run = require(path_1.default.join(cacheDir, main));
    run = run.main(query);
    if (run instanceof Promise)
        run = await run;
}
function runNpm(param, cwd) {
    return new Promise((resolve, reject) => {
        const processC = (0, child_process_1.spawn)('npm', param, {
            cwd,
            stdio: 'ignore'
        });
        processC.on('close', resolve);
        processC.on('error', (err) => {
            reject(err);
        });
    });
}
async function NpmInstall(dependencies, tagerDir) {
    const temp = new index_js_3.default(path_1.default.join(require("os").tmpdir(), "mbler"));
    await temp.init();
    const { dir } = temp;
    await promises_1.default.writeFile(path_1.default.join(dir, "package.json"), JSON.stringify({
        name: "",
        description: "",
        version: "0.0.1",
        type: "commjs"
    }));
    const rel = await runNpm(["install", dependencies], dir);
    if (rel !== 0)
        throw new Error(`npm package install falled`);
    const ModDor = path_1.default.join(dir, "node_modules");
    // 复制到目标目录
    await copy(ModDor, tagerDir);
    await temp.remove();
}
function copy(source, out) {
    return new Promise((then, error) => promises_1.default.readdir(source)
        .then((data) => Promise.all(data
        .map((file) => utils.copy(path_1.default.join(source, file), path_1.default.join(out, file)))).then(() => then()))
        .catch(error));
}
module.exports = async function workDirFunction(workDir, _dirname, param = "") {
    param = param.trim();
    dirname = _dirname;
    // 如果已经初始化了
    try {
        if (!workDir)
            throw new Error("Wrok Dir is undefined");
        if (await utils.isMblerProject(workDir))
            throw new Error("WorkDir is init You shouldn't use 'create' command");
        // 缓存id
        const CreateId = index_js_1.default.fromString(`ul-to-${param}`);
        const cacheDir = path_1.default.join(process.cwd(), "lib/initializer-cache", CreateId);
        // 如果缓存存在
        if (await utils.FileExsit(cacheDir)) {
            await Load(cacheDir, workDir);
            // 不存在缓存
        }
        else {
            const dir = utils.join(dirname, param);
            // 尝试匹配为git url
            if (regex.test(param)) {
                await index_js_2.default.clone(param, cacheDir);
            }
            else if (param.startsWith(npmStart)) {
                // 如果是 npm 包，需要加上 npm: 前缀
                const packageName = param.slice(npmStart.length);
                // 开始npm安装
                await NpmInstall(packageName, cacheDir);
            }
            else if (await utils.FileExsit(dir)) {
                // 情况 : 输入路径
                await copy(param, cacheDir);
            }
            else {
                throw new Error("Package source not match");
            }
            await Load(cacheDir, workDir);
        }
    }
    catch (err) {
        console.error(`加载模板初始化失败 错误信息\n${err.stack}`);
    }
};
