"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FileSystemCompare = exports.RomPatch = exports.FilePatch = void 0;
const Z64RomTools_1 = require("./Z64RomTools");
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const Z64LibSupportedGames_1 = require("./Z64LibSupportedGames");
class FilePatch {
    offset;
    value;
    constructor(offset, value) {
        this.offset = offset;
        this.value = value;
    }
}
exports.FilePatch = FilePatch;
class RomPatch {
    finder = "";
    hash;
    data = new Array();
    constructor(hash) {
        this.hash = hash;
    }
}
exports.RomPatch = RomPatch;
class FileSystemCompare {
    ModLoader;
    game;
    totalDMAEntries;
    ignoreEntries = [];
    constructor(ModLoader, game) {
        this.ModLoader = ModLoader;
        this.game = game;
        switch (game) {
            case Z64LibSupportedGames_1.Z64LibSupportedGames.OCARINA_OF_TIME: {
                this.totalDMAEntries = 1509;
                this.ignoreEntries.push(502);
                this.ignoreEntries.push(503);
                break;
            }
            case Z64LibSupportedGames_1.Z64LibSupportedGames.DEBUG_OF_TIME: {
                this.totalDMAEntries = 0;
                break;
            }
            case Z64LibSupportedGames_1.Z64LibSupportedGames.MAJORAS_MASK: {
                this.totalDMAEntries = 1551;
                this.ignoreEntries.push(653);
                this.ignoreEntries.push(654);
                this.ignoreEntries.push(655);
                this.ignoreEntries.push(656);
                this.ignoreEntries.push(657);
                break;
            }
        }
    }
    dumpVanilla(rom) {
        let tools = new Z64RomTools_1.Z64RomTools(this.ModLoader, this.game);
        let total = this.totalDMAEntries;
        let target = global.ModLoader["startdir"] + "/vanilla";
        if (fs_extra_1.default.existsSync(target)) {
            fs_extra_1.default.removeSync(target);
        }
        if (!fs_extra_1.default.existsSync(target)) {
            fs_extra_1.default.mkdirSync(target);
        }
        for (let i = 0; i < total; i++) {
            console.log(i);
            let buf = tools.decompressDMAFileFromRom(rom, i);
            fs_extra_1.default.writeFileSync(path_1.default.join(target, i + ".bin"), buf);
        }
    }
    dumpDirty(rom) {
        let tools = new Z64RomTools_1.Z64RomTools(this.ModLoader, this.game);
        let total = this.totalDMAEntries;
        let target = global.ModLoader["startdir"] + "/dirty";
        if (fs_extra_1.default.existsSync(target)) {
            fs_extra_1.default.removeSync(target);
        }
        if (!fs_extra_1.default.existsSync(target)) {
            fs_extra_1.default.mkdirSync(target);
        }
        for (let i = 0; i < total; i++) {
            console.log(i);
            let buf = tools.decompressDMAFileFromRom(rom, i);
            fs_extra_1.default.writeFileSync(path_1.default.join(target, i + ".bin"), buf);
        }
    }
    compare(ModLoader, o = "out.json") {
        let v = global.ModLoader["startdir"] + "/vanilla";
        let d = global.ModLoader["startdir"] + "/dirty";
        let dest = global.ModLoader["startdir"] + "/patches";
        if (!fs_extra_1.default.existsSync(dest)) {
            fs_extra_1.default.mkdirSync(dest);
        }
        let total = this.totalDMAEntries;
        let patches = {};
        for (let i = 3; i < total; i++) {
            if (this.ignoreEntries.indexOf(i) > -1) {
                continue;
            }
            let buf1 = fs_extra_1.default.readFileSync(path_1.default.join(v, i + ".bin"));
            let buf2 = fs_extra_1.default.readFileSync(path_1.default.join(d, i + ".bin"));
            for (let j = 0; j < buf1.byteLength; j++) {
                if (buf1[j] !== buf2[j]) {
                    if (!patches.hasOwnProperty(i)) {
                        patches[i] = new RomPatch(ModLoader.utils.hashBuffer(buf1));
                        console.log(i);
                    }
                    patches[i].finder = "DMA:0x" + i.toString(16);
                    patches[i].data.push(new FilePatch(j, buf2[j]));
                }
            }
        }
        let rp = [];
        Object.keys(patches).forEach((key) => {
            rp.push(patches[key]);
        });
        fs_extra_1.default.writeFileSync(path_1.default.join(dest, o), JSON.stringify(rp, null, 2));
    }
}
exports.FileSystemCompare = FileSystemCompare;
//# sourceMappingURL=FileSystemCompare.js.map