use crate::model::Primitive;

#[derive(Debug, Clone, Copy)]
pub struct JniPrimitiveInfo {
    pub kotlin_type: &'static str,
    pub jni_type: &'static str,
    pub signature: &'static str,
    pub c_type: &'static str,
    pub call_suffix: &'static str,
    pub invoker_suffix: &'static str,
    pub default_value: &'static str,
    pub callback_default: &'static str,
    pub array_type: &'static str,
    pub new_array_fn: &'static str,
    pub set_array_fn: &'static str,
    pub to_unsigned: Option<&'static str>,
    pub to_signed: Option<&'static str>,
    pub vec_to_unsigned: Option<&'static str>,
    pub jni_cast: Option<&'static str>,
    pub jni_return_cast: Option<&'static str>,
    pub jni_param_cast: Option<&'static str>,
}

pub const fn info(p: Primitive) -> JniPrimitiveInfo {
    match p {
        Primitive::Bool => JniPrimitiveInfo {
            kotlin_type: "Boolean",
            jni_type: "jboolean",
            signature: "Z",
            c_type: "bool",
            call_suffix: "Boolean",
            invoker_suffix: "Bool",
            default_value: "false",
            callback_default: "false",
            array_type: "jbooleanArray",
            new_array_fn: "NewBooleanArray",
            set_array_fn: "SetBooleanArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::I8 => JniPrimitiveInfo {
            kotlin_type: "Byte",
            jni_type: "jbyte",
            signature: "B",
            c_type: "int8_t",
            call_suffix: "Byte",
            invoker_suffix: "I8",
            default_value: "0",
            callback_default: "0",
            array_type: "jbyteArray",
            new_array_fn: "NewByteArray",
            set_array_fn: "SetByteArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::U8 => JniPrimitiveInfo {
            kotlin_type: "UByte",
            jni_type: "jbyte",
            signature: "B",
            c_type: "uint8_t",
            call_suffix: "Byte",
            invoker_suffix: "I8",
            default_value: "0u",
            callback_default: "0",
            array_type: "jbyteArray",
            new_array_fn: "NewByteArray",
            set_array_fn: "SetByteArrayRegion",
            to_unsigned: Some("toUByte()"),
            to_signed: Some("toByte()"),
            vec_to_unsigned: Some("asUByteArray().toList()"),
            jni_cast: Some("(jbyte)"),
            jni_return_cast: Some(".toInt()"),
            jni_param_cast: Some("toUInt()"),
        },
        Primitive::I16 => JniPrimitiveInfo {
            kotlin_type: "Short",
            jni_type: "jshort",
            signature: "S",
            c_type: "int16_t",
            call_suffix: "Short",
            invoker_suffix: "I16",
            default_value: "0",
            callback_default: "0",
            array_type: "jshortArray",
            new_array_fn: "NewShortArray",
            set_array_fn: "SetShortArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::U16 => JniPrimitiveInfo {
            kotlin_type: "UShort",
            jni_type: "jshort",
            signature: "S",
            c_type: "uint16_t",
            call_suffix: "Short",
            invoker_suffix: "I16",
            default_value: "0u",
            callback_default: "0",
            array_type: "jshortArray",
            new_array_fn: "NewShortArray",
            set_array_fn: "SetShortArrayRegion",
            to_unsigned: Some("toUShort()"),
            to_signed: Some("toShort()"),
            vec_to_unsigned: Some("map { it.toUShort() }"),
            jni_cast: Some("(jshort)"),
            jni_return_cast: Some(".toInt()"),
            jni_param_cast: Some("toUInt()"),
        },
        Primitive::I32 => JniPrimitiveInfo {
            kotlin_type: "Int",
            jni_type: "jint",
            signature: "I",
            c_type: "int32_t",
            call_suffix: "Int",
            invoker_suffix: "I32",
            default_value: "0",
            callback_default: "0",
            array_type: "jintArray",
            new_array_fn: "NewIntArray",
            set_array_fn: "SetIntArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::U32 => JniPrimitiveInfo {
            kotlin_type: "UInt",
            jni_type: "jint",
            signature: "I",
            c_type: "uint32_t",
            call_suffix: "Int",
            invoker_suffix: "I32",
            default_value: "0u",
            callback_default: "0",
            array_type: "jintArray",
            new_array_fn: "NewIntArray",
            set_array_fn: "SetIntArrayRegion",
            to_unsigned: Some("toUInt()"),
            to_signed: Some("toInt()"),
            vec_to_unsigned: Some("asUIntArray().toList()"),
            jni_cast: Some("(jint)"),
            jni_return_cast: Some(".toInt()"),
            jni_param_cast: Some("toUInt()"),
        },
        Primitive::I64 => JniPrimitiveInfo {
            kotlin_type: "Long",
            jni_type: "jlong",
            signature: "J",
            c_type: "int64_t",
            call_suffix: "Long",
            invoker_suffix: "I64",
            default_value: "0",
            callback_default: "0L",
            array_type: "jlongArray",
            new_array_fn: "NewLongArray",
            set_array_fn: "SetLongArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::U64 => JniPrimitiveInfo {
            kotlin_type: "ULong",
            jni_type: "jlong",
            signature: "J",
            c_type: "uint64_t",
            call_suffix: "Long",
            invoker_suffix: "I64",
            default_value: "0u",
            callback_default: "0L",
            array_type: "jlongArray",
            new_array_fn: "NewLongArray",
            set_array_fn: "SetLongArrayRegion",
            to_unsigned: Some("toULong()"),
            to_signed: Some("toLong()"),
            vec_to_unsigned: Some("asULongArray().toList()"),
            jni_cast: Some("(jlong)"),
            jni_return_cast: Some(".toLong()"),
            jni_param_cast: Some("toULong()"),
        },
        Primitive::ISize => JniPrimitiveInfo {
            kotlin_type: "Long",
            jni_type: "jlong",
            signature: "J",
            c_type: "intptr_t",
            call_suffix: "Long",
            invoker_suffix: "I64",
            default_value: "0",
            callback_default: "0L",
            array_type: "jlongArray",
            new_array_fn: "NewLongArray",
            set_array_fn: "SetLongArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::USize => JniPrimitiveInfo {
            kotlin_type: "ULong",
            jni_type: "jlong",
            signature: "J",
            c_type: "uintptr_t",
            call_suffix: "Long",
            invoker_suffix: "I64",
            default_value: "0u",
            callback_default: "0L",
            array_type: "jlongArray",
            new_array_fn: "NewLongArray",
            set_array_fn: "SetLongArrayRegion",
            to_unsigned: Some("toULong()"),
            to_signed: Some("toLong()"),
            vec_to_unsigned: Some("asULongArray().toList()"),
            jni_cast: Some("(jlong)"),
            jni_return_cast: Some(".toLong()"),
            jni_param_cast: Some("toULong()"),
        },
        Primitive::F32 => JniPrimitiveInfo {
            kotlin_type: "Float",
            jni_type: "jfloat",
            signature: "F",
            c_type: "float",
            call_suffix: "Float",
            invoker_suffix: "F32",
            default_value: "0.0f",
            callback_default: "0.0f",
            array_type: "jfloatArray",
            new_array_fn: "NewFloatArray",
            set_array_fn: "SetFloatArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
        Primitive::F64 => JniPrimitiveInfo {
            kotlin_type: "Double",
            jni_type: "jdouble",
            signature: "D",
            c_type: "double",
            call_suffix: "Double",
            invoker_suffix: "F64",
            default_value: "0.0",
            callback_default: "0.0",
            array_type: "jdoubleArray",
            new_array_fn: "NewDoubleArray",
            set_array_fn: "SetDoubleArrayRegion",
            to_unsigned: None,
            to_signed: None,
            vec_to_unsigned: None,
            jni_cast: None,
            jni_return_cast: None,
            jni_param_cast: None,
        },
    }
}
