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;

    static QR_PREFIX : &str = "DLSMK_";

    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;
            }
        };

        if !qrcode.starts_with(QR_PREFIX) {
            put_data(&env, &qrdata, "error", "qrcode prefix error");
            return JNI_FALSE;
        }
        let qrcode = match qrcode.strip_prefix(QR_PREFIX) {
            Some(q) => String::from(q),
            None => {
                put_data(&env, &qrdata, "error", "qrcode prefix error");
                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
            }
        }
    }
}
