import {NativeStruct} from "./NativeStruct";
import {il2cppApi} from "../il2cppApi";
import {log} from "../../logger";
import {soName} from "../../config";
import {Il2CppClass} from "./Il2CppClass";
import {Il2CppGenericMethod} from "./Il2CppGenericMethod";


const METHOD_INFO_OFFSET_SLOT=76;
export class MethodInfo extends NativeStruct{

    getGenericMethod(){
            return new Il2CppGenericMethod(this.add(0x38));
    }
    getFlags(){
        return il2cppApi.il2cpp_method_get_flags(this,0);
    }

    getMethodPointer(){
        return il2cppApi.il2cpp_method_get_pointer(this);
    }
    getMethodPointerOffsetToInt(){
        let methodPointer = this.getMethodPointer();
        // log("methodPointer:"+methodPointer);
        if (methodPointer.isNull()){
            return 0;
        }
        let baseAddr = Module.findBaseAddress(soName);
        return  methodPointer - baseAddr;
    }
    getMethodPointerOffset(){
        let methodPointer = this.getMethodPointer();
        log("methodPointer:"+methodPointer);
        if (methodPointer.isNull()){
            return "0x0";
        }
        let baseAddr = Module.findBaseAddress(soName);
        let number = methodPointer-baseAddr;
        return number.toString(16).toUpperCase();
    }
    getSlot(){
        return this.add(METHOD_INFO_OFFSET_SLOT).readU16();
    }
    name(){
        return il2cppApi.il2cpp_method_get_name(this).readCString();
    }
    getParamCount(){
        return il2cppApi.il2cpp_method_get_param_count(this);
    }
    getParam(index){
        return il2cppApi.il2cpp_method_get_param(this,index);
    }
    getParamName(index){
        return il2cppApi.il2cpp_method_get_param_name(this,index).readCString();
    }
    /**
     * 获取返回类型
     * @returns {Il2CppType}
     */
    getReturnType(){
        return il2cppApi.il2cpp_method_get_return_type(this);
    }
    is_generic(){
        return il2cppApi.il2cpp_method_is_generic(this);
    }
    is_inflated(){
        return il2cppApi.il2cpp_method_is_inflated(this);
    }
    getClass(){
        return new Il2CppClass(il2cppApi.il2cpp_method_get_class(this));
    }

    invoker_method() {
        return this.add(0x8).readPointer();
    }
}