import {logColor, LogColor} from "../logger";
const IS_SAVE_ALL_JS = false;
const TARGET_PACKAGE = "com.rbigkic.yyydsj";

const targetModuleName = "libcocos2djs.so";
let TAGET_DATA_FILES = `/data/data/${TARGET_PACKAGE}/files`;

const PROJECT_PATH = `${TAGET_DATA_FILES}/project.js`;
const RE_PROJECT_PATH = `${TAGET_DATA_FILES}/index.jsc`;

export let HookYDSJ = {
    start: function () {
        Java.perform(function () {
            Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
                onEnter: function (args) {
                    var soName = args[0].readCString();
                    // console.log("dlopen called with: " + soName);
                    // 获取正在加载的模块的名称
                    var moduleName = Memory.readUtf8String(args[0]);
                    this.isTargetModule = (moduleName.indexOf(targetModuleName) !== -1);
                },
                onLeave: function (ret) {
                    if (this.isTargetModule) {
                        HookYDSJ.hook();
                    }
                }
            });
        })
    }, hook: function () {
        logColor("HookLDGP start", LogColor.RED_BG);
        let addressBase = Module.findBaseAddress(targetModuleName);

        function saveString(scriptString) {

            logColor("=======开始写入========", LogColor.GREEN_TEXT);
            var file = new File(PROJECT_PATH, "wb");
            file.write(scriptString);
            file.flush();
            file.close();
            logColor("=======写入完成========", LogColor.GREEN_TEXT);
        }

        function createDir(saveFilePath) {
            let path = require('path'); // 引入path模块,假设Frida环境支持或者有类似的路径处理方法

            // 分离目录路径和文件名
            let dirPath = path.dirname(saveFilePath);
            let fileName = path.basename(saveFilePath);

            // 检查目录是否存在,不存在则创建
            Java.perform(function () {
                // 使用 Java 的 File 类
                var File = Java.use("java.io.File");

                // 目标目录路径

                // 创建 File 对象表示这个目录
                var targetDir = File.$new(dirPath);

                // 检查目录是否存在
                if (!targetDir.exists()) {
                    // 目录不存在,尝试创建目录
                    var success = targetDir.mkdirs();
                    if (success) {
                        logColor("目录创建成功:" + saveFilePath, LogColor.GREEN_TEXT)
                    } else {
                        logColor("目录创建失败:" + saveFilePath, LogColor.RED_TEXT)
                    }
                } else {
                    logColor("目录已存在:" + saveFilePath, LogColor.RED_TEXT)
                }
            });
        }
        function saveAllJs(args) {
            if (IS_SAVE_ALL_JS) {
                let saveFilePath = `${TAGET_DATA_FILES}/saved_js/`;
                //判断saveFilePath是否存在,不存在则创建
                if (!args[4].isNull()) {//这个应该是别名
                    var jsName = args[4].readUtf8String();
                    let filePath = `${saveFilePath}${jsName}`;
                    createDir(filePath);
                    var scriptString = args[1].readUtf8String();

                    logColor(`=======开始写入--${jsName}--========`, LogColor.GREEN_TEXT);
                    var file = new File(filePath, "wb");
                    file.write(scriptString);
                    file.flush();
                    file.close();
                    logColor(`=======写入--${jsName}--完成========`, LogColor.GREEN_TEXT);
                }
            }
            return IS_SAVE_ALL_JS;
        }

        try {
            logColor("addressBase: " + addressBase, LogColor.RED_BG);
            Module.ensureInitialized(targetModuleName);
            var targetFunctionAddress = addressBase.add(0x000008E3FE4);
            Interceptor.attach(targetFunctionAddress, {
                onEnter: function (args) {
                    // console.log("evalString Function called");
                    //判断args是否为空
                    if (args === null) {
                        console.log("evalString Function args is null");
                        return;
                    }

                    //用颜色打印所有的参数
                    if (!args[4].isNull()) {//这个应该是别名
                        var contextName = args[4].readUtf8String();
                        console.log("脚本别名" + contextName);
                        var scriptLength = args[2].toInt32();
                        console.log("Length of code: " + scriptLength);

                        if (saveAllJs(args)){
                            logColor("----------保存所有脚本-----", LogColor.RED_BG);
                            return;
                        }

                        if (contextName.indexOf("assets/main/index.jsc") !== -1) {
                            //保存最新的版本
                            // var scriptString = args[1].readUtf8String();
                            // console.log("JavaScript scriptString: " + scriptString);
                            // saveString(scriptString);
                            // return 1;

                            this.replaced = 1;
                            //获取当前时间
                            this.startTime = new Date().getTime();
                            // return 1;

                            var env = Java.vm.getEnv();

                            let libCliSo = Module.load("/data/data/com.rbigkic.yyydsj/files/libcli.so");
                            logColor("libCliSo: " + libCliSo, LogColor.GREEN_TEXT);
                            let readFileAddress = libCliSo.findExportByName("readFile");
                            logColor("readFile: " + readFileAddress, LogColor.GREEN_TEXT);
                            let readFile = new NativeFunction(readFileAddress, 'pointer', ['pointer', "pointer"]);
                            let filePath = Memory.allocUtf8String(RE_PROJECT_PATH);

                            let jByteArray = readFile(env.handle, filePath);
                            // 处理返回的 jbyteArray
                            var length = env.getArrayLength(jByteArray);
                            var buffer = env.getByteArrayElements(jByteArray, null);
                            args[1] = ptr(buffer);
                            args[2] = ptr(length);
                            // TraceTools.crash2Trace(this.context);

                            // var scriptEngine = args[0];
                            // console.log("JavaScript scriptEngine add: " + scriptEngine);
                            //
                            // var reProjectJs = readProjectJs();
                            // args[1] = reProjectJs.buffer;
                            // args[2] = reProjectJs.length;
                            // args[3] = reProjectJs.addPtr;
                            // logColor("reProjectJs: " + reProjectJs.length, LogColor.RED_BG);
                            //
                            var scriptLength = args[2].toInt32();
                            console.log("Length of code: " + scriptLength);
                            //
                            console.log("Result storage: " + args[3] + " typeof:" + typeof args[3]);
                        }
                    }
                },
                onLeave: function (retval) {
                    //尝试所有类型的返回值
                    if (this.replaced) {
                        console.log("json 替换结果:", retval.toInt32() === 1);
                        var endTime = new Date().getTime();
                        console.log("耗时: " + (endTime - this.startTime) + "ms");
                    }
                }
            });
        } catch (e) {

            console.log("error: " + e);
        }
    }
}