package com.axis.innovators.box.gui;

import org.fife.ui.autocomplete.BasicCompletion;
import org.fife.ui.autocomplete.DefaultCompletionProvider;

public class FridaSyntax {
    public static void addFridaCompletions(DefaultCompletionProvider provider) {
        // Java 相关
        provider.addCompletion(new BasicCompletion(provider,
                "Java.perform(function() {\n    // Your code here\n});",
                "Java.perform",
                "在 Java 上下文中执行代码"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.choose('$className$', {\n" +
                        "  onMatch: function(instance) {\n    // Handle instance\n  },\n" +
                        "  onComplete: function() {\n    // Complete handler\n  }\n})",
                "Java.choose",
                "枚举 Java 对象实例"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.use('$className$')",
                "Java.use",
                "获取 Java 类的引用"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.enumerateLoadedClasses({\n" +
                        "  onMatch: function(className) {\n    // Handle class name\n  },\n" +
                        "  onComplete: function() {\n    // Complete handler\n  }\n})",
                "Java.enumerateLoadedClasses",
                "枚举已加载的 Java 类"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.enumerateMethods('$className$')",
                "Java.enumerateMethods",
                "枚举指定 Java 类的方法"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.scheduleOnMainThread(function() {\n    // Your code here\n});",
                "Java.scheduleOnMainThread",
                "在主线程中执行代码"));

        provider.addCompletion(new BasicCompletion(provider,
                "Java.deoptimizeEverything()",
                "Java.deoptimizeEverything",
                "禁用 JIT 优化"));

        // 模块和符号相关
        provider.addCompletion(new BasicCompletion(provider,
                "Module.findExportByName('$module$', '$name$')",
                "Module.findExportByName",
                "查找模块导出函数"));

        provider.addCompletion(new BasicCompletion(provider,
                "Module.findBaseAddress('$module$')",
                "Module.findBaseAddress",
                "查找模块的基地址"));

        provider.addCompletion(new BasicCompletion(provider,
                "Module.enumerateImports('$module$')",
                "Module.enumerateImports",
                "枚举模块的导入函数"));

        provider.addCompletion(new BasicCompletion(provider,
                "Module.enumerateExports('$module$')",
                "Module.enumerateExports",
                "枚举模块的导出函数"));

        provider.addCompletion(new BasicCompletion(provider,
                "Module.enumerateSymbols('$module$')",
                "Module.enumerateSymbols",
                "枚举模块的符号"));

        provider.addCompletion(new BasicCompletion(provider,
                "Module.load('$path$')",
                "Module.load",
                "加载指定路径的模块"));

        // 内存操作相关
        provider.addCompletion(new BasicCompletion(provider,
                "Memory.scan('$address$', $size$, '$pattern$', {\n" +
                        "  onMatch: function(address, size) {\n    // Handle match\n  },\n" +
                        "  onComplete: function() {\n    // Complete handler\n  }\n})",
                "Memory.scan",
                "扫描内存中的指定模式"));

        provider.addCompletion(new BasicCompletion(provider,
                "Memory.alloc($size$)",
                "Memory.alloc",
                "分配指定大小的内存"));

        provider.addCompletion(new BasicCompletion(provider,
                "Memory.copy('$destination$', '$source$', $size$)",
                "Memory.copy",
                "复制内存数据"));

        provider.addCompletion(new BasicCompletion(provider,
                "Memory.protect('$address$', $size$, '$protection$')",
                "Memory.protect",
                "修改内存保护属性"));

        provider.addCompletion(new BasicCompletion(provider,
                "Memory.readByteArray('$address$', $size$)",
                "Memory.readByteArray",
                "读取内存中的字节数组"));

        provider.addCompletion(new BasicCompletion(provider,
                "Memory.writeByteArray('$address$', [$bytes$])",
                "Memory.writeByteArray",
                "写入字节数组到内存"));

        // 拦截器相关
        provider.addCompletion(new BasicCompletion(provider,
                "Interceptor.attach('$address$', {\n" +
                        "  onEnter: function(args) {\n    // Handle enter\n  },\n" +
                        "  onLeave: function(retval) {\n    // Handle leave\n  }\n})",
                "Interceptor.attach",
                "附加拦截器到指定地址"));

        provider.addCompletion(new BasicCompletion(provider,
                "Interceptor.replace('$address$', new NativeCallback(function(args) {\n    // Your code here\n}, '$returnType$', ['$argTypes$']))",
                "Interceptor.replace",
                "替换函数实现"));

        provider.addCompletion(new BasicCompletion(provider,
                "Interceptor.detach('$address$')",
                "Interceptor.detach",
                "分离拦截器"));

        // 进程和线程相关
        provider.addCompletion(new BasicCompletion(provider,
                "Process.enumerateModules()",
                "Process.enumerateModules",
                "枚举已加载的模块"));

        provider.addCompletion(new BasicCompletion(provider,
                "Process.enumerateThreads()",
                "Process.enumerateThreads",
                "枚举进程中的线程"));

        provider.addCompletion(new BasicCompletion(provider,
                "Process.getCurrentThreadId()",
                "Process.getCurrentThreadId",
                "获取当前线程 ID"));

        provider.addCompletion(new BasicCompletion(provider,
                "Process.setExceptionHandler(function(exception) {\n    // Handle exception\n})",
                "Process.setExceptionHandler",
                "设置异常处理函数"));

        // 文件系统相关
        provider.addCompletion(new BasicCompletion(provider,
                "File.open('$path$', '$mode$')",
                "File.open",
                "打开文件"));

        provider.addCompletion(new BasicCompletion(provider,
                "File.read('$file$', $size$)",
                "File.read",
                "读取文件内容"));

        provider.addCompletion(new BasicCompletion(provider,
                "File.write('$file$', $data$)",
                "File.write",
                "写入数据到文件"));

        provider.addCompletion(new BasicCompletion(provider,
                "File.remove('$path$')",
                "File.remove",
                "删除文件"));

        // 网络相关
        provider.addCompletion(new BasicCompletion(provider,
                "Socket.listen('$address$', $port$)",
                "Socket.listen",
                "监听指定地址和端口"));

        provider.addCompletion(new BasicCompletion(provider,
                "Socket.connect('$address$', $port$)",
                "Socket.connect",
                "连接到指定地址和端口"));

        provider.addCompletion(new BasicCompletion(provider,
                "Socket.read('$socket$', $size$)",
                "Socket.read",
                "从套接字读取数据"));

        provider.addCompletion(new BasicCompletion(provider,
                "Socket.write('$socket$', $data$)",
                "Socket.write",
                "写入数据到套接字"));

        // 其他实用工具
        provider.addCompletion(new BasicCompletion(provider,
                "send($message$)",
                "send",
                "发送消息到 Frida 客户端"));

        provider.addCompletion(new BasicCompletion(provider,
                "recv(function(message) {\n    // Handle message\n})",
                "recv",
                "接收来自 Frida 客户端的消息"));

        provider.addCompletion(new BasicCompletion(provider,
                "hexdump('$address$', { offset: $offset$, length: $length$ })",
                "hexdump",
                "以十六进制格式打印内存内容"));

        provider.addCompletion(new BasicCompletion(provider,
                "console.log('$message$')",
                "console.log",
                "打印日志信息"));

        provider.addCompletion(new BasicCompletion(provider,
                "console.error('$message$')",
                "console.error",
                "打印错误信息"));

        provider.addCompletion(new BasicCompletion(provider,
                "setTimeout(function() {\n    // Your code here\n}, $delay$)",
                "setTimeout",
                "设置延时执行"));

        provider.addCompletion(new BasicCompletion(provider,
                "setInterval(function() {\n    // Your code here\n}, $interval$)",
                "setInterval",
                "设置定时执行"));
    }

    public static void addBasicCompletions(DefaultCompletionProvider provider) {
        String[] jsKeywords = {"function", "var", "let", "const", "if", "else",
                "for", "while(/* logic */)", "try", "catch", "true", "false","()", "for (var i = 0; i < ; i++) {\n" +
                "            \n" +
                "}"};

        String[] fridaTypes = {
                "Frida", "Process", "Module", "ModuleMap", "Memory", "Thread", "ThreadBacktrace",
                "ThreadDetails", "Instruction", "Interceptor", "NativePointer", "NativeFunction",
                "NativeCallback", "SystemFunction", "SystemFunctionOptions", "SocketListener",
                "SocketConnection", "File", "InputStream", "OutputStream", "Database", "Statement",
                "SqliteError", "ObjC", "ObjC.Object", "ObjC.Class", "ObjC.Protocol", "ObjC.Block",
                "ObjC.Method", "ObjC.Ivar", "ObjC.Property", "ObjC.Selector", "Java", "Java.Class",
                "Java.Method", "Java.Field", "Java.Scheduler", "Java.Cast", "Java.Perform", "Java.use",
                "Java.available", "Java.scheduleOnMainThread", "Java.deoptimizeEverything",
                "Java.enumerateLoadedClasses", "Java.enumerateMethods", "Java.vm", "Java.vm.tryGetEnv",
                "Java.vm.perform", "Java.vm.getEnv", "Java.vm.tryGetEnv", "Java.vm.tryGetEnv","Script",
                "ScriptRuntime", "ScriptSource", "ScriptOptions", "CompiledScript",
                "ScriptExports", "ScriptMessage", "ScriptMessageHandler", "ScriptPostMessageHandler",
                "ScriptUnloadHandler", "ScriptDestroyHandler", "ScriptLogHandler", "ScriptErrorHandler",
                "ScriptDebugHandler", "ScriptStdinHandler", "ScriptStdoutHandler", "ScriptStderrHandler",
                "Memory.scan", "Memory.scanSync", "Memory.alloc", "Memory.allocUtf8String",
                "Memory.allocAnsiString", "Memory.copy", "Memory.protect", "Memory.readByteArray",
                "Memory.readCString", "Memory.readUtf8String", "Memory.readAnsiString",
                "Memory.writeByteArray", "Memory.writeUtf8String", "Memory.writeAnsiString",
                "Memory.writePointer", "Memory.writeS8", "Memory.writeS16", "Memory.writeS32",
                "Memory.writeS64", "Memory.writeU8", "Memory.writeU16", "Memory.writeU32",
                "Memory.writeU64", "Memory.writeFloat", "Memory.writeDouble",
                "Process.id", "Process.arch", "Process.platform", "Process.pageSize", "Process.pointerSize",
                "Process.codeSigningPolicy", "Process.enumerateThreads", "Process.enumerateModules",
                "Process.enumerateRanges", "Process.enumerateMallocRanges", "Process.enumerateModuleRanges",
                "Process.findModuleByName", "Process.findModuleByAddress", "Process.getModuleByName",
                "Process.getModuleByAddress", "Process.getCurrentThreadId", "Process.getThreadById",
                "Process.setExceptionHandler", "Module.load", "Module.ensureInitialized",
                "Module.findBaseAddress", "Module.findExportByName", "Module.enumerateImports",
                "Module.enumerateExports", "Module.enumerateSymbols", "Module.enumerateSections",
                "Module.enumerateDependencies", "Module.findExportByAddress", "Module.getExportByName",
                "Module.getExportByAddress", "Interceptor.attach", "Interceptor.detach",
                "Interceptor.replace", "Interceptor.revert", "Interceptor.flush", "NativePointer.isNull",
                "NativePointer.add", "NativePointer.sub", "NativePointer.and", "NativePointer.or",
                "NativePointer.xor", "NativePointer.shr", "NativePointer.shl", "NativePointer.compare",
                "NativePointer.toInt32", "NativePointer.toUInt32", "NativePointer.toString",
                "NativePointer.readPointer", "NativePointer.writePointer", "NativePointer.readS8",
                "NativePointer.readS16", "NativePointer.readS32", "NativePointer.readS64",
                "NativePointer.readU8", "NativePointer.readU16", "NativePointer.readU32",
                "NativePointer.readU64", "NativePointer.readFloat", "NativePointer.readDouble",
                "NativePointer.writeS8", "NativePointer.writeS16", "NativePointer.writeS32",
                "NativePointer.writeS64", "NativePointer.writeU8", "NativePointer.writeU16",
                "NativePointer.writeU32", "NativePointer.writeU64", "NativePointer.writeFloat",
                "NativePointer.writeDouble", "File.open", "File.close", "File.read", "File.write",
                "File.flush", "File.seek", "File.tell", "File.size", "File.copy", "File.move",
                "File.remove", "File.exists", "File.isDirectory", "File.list", "Database.open",
                "Database.close", "Database.execute", "Database.prepare", "Database.step",
                "Database.reset", "Database.finalize", "Database.lastInsertRowId", "Database.changes",
                "Database.backup", "Socket.listen", "Socket.connect", "Socket.bind", "Socket.accept",
                "Socket.read", "Socket.write", "Socket.close", "Socket.shutdown", "Socket.getPeerName",
                "Socket.getSockName", "Socket.setTimeout", "Socket.setNoDelay", "Socket.setKeepAlive",
                "ObjC.available", "ObjC.classes", "ObjC.protocols", "ObjC.registerClass", "ObjC.bind",
                "ObjC.unbind", "ObjC.schedule", "ObjC.perform", "ObjC.choose", "ObjC.enumerateLoadedClasses",
                "ObjC.enumerateMethods", "ObjC.enumerateProperties", "ObjC.enumerateIvars",
                "ObjC.enumerateProtocols", "Java.enumerateLoadedClasses", "Java.enumerateMethods",
                "Java.enumerateFields", "Java.enumerateClassLoaders", "Java.choose",
                "Java.scheduleOnMainThread", "Java.perform", "Java.performNow", "Java.performSync",
                "Java.deoptimizeEverything", "Java.vm.getEnv", "Java.vm.tryGetEnv", "Java.vm.perform",
                "Java.vm.tryGetEnv", "send", "recv", "rpc", "WeakRef", "WeakCallback", "ptr", "NULL",
                "hexdump", "console.log", "console.warn", "console.error", "console.dir", "console.trace",
                "setTimeout", "clearTimeout", "setInterval", "clearInterval", "setImmediate", "clearImmediate"};

        for (String type : fridaTypes) {
            provider.addCompletion(new BasicCompletion(provider, type));
        }

        for (String kw : jsKeywords) {
            provider.addCompletion(new BasicCompletion(provider, kw));
        }
    }
}
