extern crate base64;
extern crate hex;

#[cfg(test)]
mod tests {
    #[test]
    fn it_works() {
        assert_eq!(2 + 2, 4);
    }

    #[test]
    fn test_key() {
        let key = "wDp3/3NPEi+R0peokVv010GkDk1mRTp3tUB/lCEVRAA=";
        let key_buffer = base64::decode_config(key, base64::STANDARD).unwrap();
        let s = hex::encode(key_buffer.as_slice());
        let key_string = hex::decode(format!("{}{:04x}{:02x}", s, 5, 10)).unwrap();
        println!(
            "key : {}",
            base64::encode_config(key_string, base64::URL_SAFE)
        );
    }
}

// use std::ffi::{CStr, CString};
// use std::os::raw::{c_char, c_uchar, c_ulong};

// #[no_mangle]
// pub extern "C" fn dlsmk_decode(
//     key: *const c_uchar,
//     qrcode: *const c_uchar,
//     qrlen: c_ulong,
// ) -> *mut c_char {
//     CString::new("Hello ".to_owned()).unwrap().into_raw()
// }

#[cfg(any(target_family = "unix", target_os = "android"))]
#[allow(non_snake_case)]
pub mod android {
    extern crate base64;
    extern crate jni;

    use self::jni::objects::{JClass, JMap, JObject, JString};
    use self::jni::sys::{jboolean, jint, jlong, jstring, JNI_FALSE, JNI_TRUE};
    use self::jni::JNIEnv;
    use std::ffi::CStr;

    use log::debug;

    use dlqrcode::DaliQrCode;

    fn put_data(env: &JNIEnv, map: &JMap, key: &str, value: &str) {
        map.put(
            *env.new_string(key).unwrap(),
            *env.new_string(value).unwrap(),
        )
        .unwrap();
    }

    #[no_mangle]
    pub unsafe extern "C" fn Java_com_supwisdom_dlsmk_DLSMKQrCode_decode(
        env: JNIEnv,
        _: JClass,
        key_hex: JString,
        qrcode: JString,
        offset: jlong,
        result: JObject,
    ) -> jboolean {
        let key = {
            let s = env
                .get_string(key_hex)
                .expect("invalid key string")
                .as_ptr();
            String::from(CStr::from_ptr(s).to_string_lossy())
        };

        let qrcode = {
            let s = env
                .get_string(qrcode)
                .expect("invalid qrcode string")
                .as_ptr();
            String::from(CStr::from_ptr(s).to_string_lossy())
        };

        let qrdata = env.get_map(result).expect("invalid qrdata map");

        let (key, step, skew) = {
            let mut k = [0u8; 32];
            if let Ok(v) = base64::decode_config(key, base64::URL_SAFE) {
                if v.len() != 35 {
                    put_data(&env, &qrdata, "error", "key format error");
                    return JNI_FALSE;
                }
                k.clone_from_slice(&v.as_slice()[..32]);
                let step = ((v[32] as u64) << 8) | (v[33] as u64);
                let skew = v[34] as u8;
                (k, step, skew)
            } else {
                put_data(
                    &env,
                    &qrdata,
                    "error",
                    "key must be hex format and 64 characters",
                );
                return JNI_FALSE;
            }
        };

        debug!("TOTP step <{}> , skew <{}>", step, skew);
        let decoder = match DaliQrCode::new(key, None, Some(step), Some(skew), None) {
            Ok(d) => d,
            Err(e) => {
                let s = format!("invalid input parameter {:?}", e);
                put_data(&env, &qrdata, "error", &s);
                return JNI_FALSE;
            }
        };

        match decoder.decode(qrcode.as_ptr(), qrcode.len(), offset as i32) {
            Ok(d) => {
                put_data(&env, &qrdata, "cardno", &d.cardno);
                put_data(&env, &qrdata, "cardtype", &d.cardtype);
                put_data(&env, &qrdata, "uid", &d.uid);
                let sign = dlqrcode::transaction_sign(&d);
                put_data(&env, &qrdata, "sign", &sign);
                return JNI_TRUE;
            }
            Err(e) => {
                let s = format!("{:?}", e);
                put_data(&env, &qrdata, "error", &s);
                return JNI_FALSE;
            }
        };
    }

    const VERSION: &'static str = env!("CARGO_PKG_VERSION");

    #[no_mangle]
    pub unsafe extern "C" fn Java_com_supwisdom_dlsmk_DLSMKQrCode_version(
        env: JNIEnv,
        _: JClass,
    ) -> jstring {
        let s = env
            .new_string(String::from(VERSION))
            .expect("would't get version");
        s.into_inner()
    }

    #[no_mangle]
    pub unsafe extern "C" fn Java_com_supwisdom_dlsmk_DLSMKQrCode_genTac(
        env: JNIEnv,
        _: JClass,
        qrsign: JString,
        cardno: JString,
        amount: jint,
        termDatetime: JString,
        result: JObject,
    ) -> jboolean {
        let qrsign = {
            let s = env.get_string(qrsign).expect("invalid key string").as_ptr();
            String::from(CStr::from_ptr(s).to_string_lossy())
        };
        let cardno = {
            let s = env
                .get_string(cardno)
                .expect("invalid cardno string")
                .as_ptr();
            String::from(CStr::from_ptr(s).to_string_lossy())
        };

        let termDatetime = {
            let s = env
                .get_string(termDatetime)
                .expect("invalid datetime")
                .as_ptr();
            String::from(CStr::from_ptr(s).to_string_lossy())
        };

        let result = env.get_map(result).expect("invalid qrdata map");

        if termDatetime.len() != 14 {
            put_data(&env, &result, "error", "term datetime must be 14 chars");
            return JNI_FALSE;
        }

        match dlqrcode::transaction_tac(&cardno, amount, &termDatetime, &qrsign) {
            Ok(tac) => {
                put_data(&env, &result, "tac", &tac);
                JNI_TRUE
            }
            Err(e) => {
                put_data(&env, &result, "error", &format!("{:?}", e));
                JNI_FALSE
            }
        }
    }
}
