"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ClasspathManager = void 0;
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const currentOS = os_1.default.platform();
const normalizeOSMap = {
    win32: 'windows',
    darwin: 'osx',
    linux: 'linux'
};
const normalizeOS = normalizeOSMap[currentOS] || currentOS;
const isAllowed = (rules) => {
    if (!rules)
        return true;
    let result = null;
    for (const rule of rules) {
        const matchOS = !rule.os || rule.os.name === normalizeOS;
        if (matchOS)
            result = rule.action === "allow";
    }
    return result ?? false;
};
class ClasspathManager {
    root;
    version;
    constructor(root, version) {
        this.root = root;
        this.version = version;
    }
    mergeInheritedLibraries(versionData) {
        let merged = [...(versionData.libraries || [])];
        let currentID = versionData.inheritsFrom;
        while (currentID) {
            const jsonPath = path_1.default.join(this.root, "versions", currentID, `${currentID}.json`);
            if (!fs_1.default.existsSync(jsonPath))
                break;
            try {
                const parent = JSON.parse(fs_1.default.readFileSync(jsonPath, "utf-8"));
                merged = [...(parent.libraries || []), ...merged];
                currentID = parent.inheritsFrom;
            }
            catch {
                break;
            }
        }
        return merged;
    }
    resolveLibPath(lib) {
        const libDir = path_1.default.join(this.root, "libraries");
        const maven2Dir = path_1.default.join(this.root, "maven2");
        const candidates = [];
        if (lib.downloads?.classifiers?.jar?.path)
            candidates.push(lib.downloads.classifiers.jar.path);
        if (lib.downloads?.artifact?.path)
            candidates.push(lib.downloads.artifact.path);
        if (lib.name) {
            const [group, name, version] = lib.name.split(":");
            if (group && name && version) {
                candidates.push(path_1.default.join(...group.split("."), name, version, `${name}-${version}.jar`));
            }
        }
        for (const relPath of candidates) {
            const fromLibs = path_1.default.join(libDir, relPath);
            if (fs_1.default.existsSync(fromLibs))
                return fromLibs;
            const fromMaven = path_1.default.join(maven2Dir, relPath);
            if (fs_1.default.existsSync(fromMaven))
                return fromMaven;
        }
        return null;
    }
    buildClasspath() {
        const classpath = [];
        const seen = new Set();
        const pushIfExists = (p) => { if (!seen.has(p)) {
            classpath.push(p);
            seen.add(p);
        } };
        const libs = this.mergeInheritedLibraries(this.version)
            .filter(lib => isAllowed(lib.rules));
        const isOptiFine = this.version.id.toLowerCase().includes("optifine");
        const needsLaunchWrapper = this.version.id.startsWith("1.7") || isOptiFine || this.version.id.toLowerCase().includes("fml");
        // Rutas especiales
        let launchWrapperPath = null;
        let bootstrapPath = null;
        let universalPath = null;
        for (const lib of libs) {
            const libPath = this.resolveLibPath(lib);
            if (!libPath)
                continue;
            if (lib.name?.includes("launchwrapper"))
                launchWrapperPath = libPath;
            if (lib.name?.includes("bootstraplauncher"))
                bootstrapPath = libPath;
            if (lib.name?.includes("neoforge") && libPath.includes("universal"))
                universalPath = libPath;
        }
        if (needsLaunchWrapper) {
            if (!launchWrapperPath) {
                const lwVersion = this.version.id.startsWith("1.7") ? "1.5" : "1.12";
                launchWrapperPath = path_1.default.resolve(this.root, "libraries", "net", "minecraft", "launchwrapper", lwVersion, `launchwrapper-${lwVersion}.jar`);
            }
            pushIfExists(launchWrapperPath);
        }
        if (this.version.inheritsFrom) {
            const baseJar = path_1.default.resolve(this.root, "versions", this.version.inheritsFrom, `${this.version.inheritsFrom}.jar`);
            pushIfExists(baseJar);
        }
        const versionJar = path_1.default.resolve(this.root, "versions", this.version.id, `${this.version.id}.jar`);
        if (isOptiFine)
            pushIfExists(versionJar);
        if (bootstrapPath)
            pushIfExists(bootstrapPath);
        if (universalPath)
            pushIfExists(universalPath);
        for (const lib of libs) {
            const libPath = this.resolveLibPath(lib);
            if (!libPath)
                continue;
            if ((needsLaunchWrapper && lib.name?.includes("launchwrapper")) ||
                lib.name?.includes("bootstraplauncher") ||
                (lib.name?.includes("neoforge") && libPath.includes("universal")))
                continue;
            pushIfExists(libPath);
        }
        if (!isOptiFine)
            pushIfExists(versionJar);
        let nativesDir = path_1.default.resolve(this.root, "versions", this.version.id, "natives");
        if (this.version.inheritsFrom) {
            const parentNatives = path_1.default.resolve(this.root, "versions", this.version.inheritsFrom, "natives");
            nativesDir = nativesDir || parentNatives;
        }
        return {
            classpath,
            classpathString: classpath.join(path_1.default.delimiter),
            nativesDir
        };
    }
}
exports.ClasspathManager = ClasspathManager;
