mod jose;

use crate::jose::{deserialize_jwe_aes, deserialize_jwe_aes_2, deserialize_jwe_rsa_2, serialize_jwe_aes_2, serialize_jwe_rsa, serialize_jwe_rsa_2};
use base64::engine::general_purpose::STANDARD;
use base64::Engine;
use jose_jwk::{Jwk, Key, Rsa};
use rand::random;
use rand::rngs::ThreadRng;
use rsa::traits::{PrivateKeyParts, PublicKeyParts};
use rsa::{Oaep, Pkcs1v15Encrypt};
use sha2::Sha256;

fn main() {
    let key: [u8; 32] = random();
    let payload = b"hello world";

    let e = serialize_jwe_aes_2(payload, key).unwrap();
    println!("{}", e);

    let (d, h) = deserialize_jwe_aes(&e, &key).unwrap();
    println!("{:?}", d);
    println!("{:?}", h);

    let (d2, h2) = deserialize_jwe_aes_2(&e, key).unwrap();
    println!("{:?}", d2);
    println!("{:?}", h2);

    let rsa_key = jose::generate_rsa_key_2(2048).unwrap();
    let rsa_public_key = rsa_key.as_ref();
    let public_rsa: Rsa = rsa_public_key.into();
    // let rsa: Rsa = rsa_key.into();
    // println!("{:?}", public_rsa);
    // println!("{:?}", rsa);

    let jwk = Jwk {
        key: Key::Rsa(public_rsa),
        prm: Default::default(),
    };
    let jwk_str = serde_json::to_string(&jwk).unwrap();
    println!("{}", &jwk_str);
    // let rsa: Rsa = serde_json::from_str(&jwk_str).unwrap();
    let josekitjwk = josekit::jwk::Jwk::from_bytes(jwk_str.as_bytes()).unwrap();
    let rsa_jwe = serialize_jwe_rsa(b"hello world 001", &josekitjwk).unwrap();
    // let rsa_key_2: RsaPrivateKey = rsa.try_into().unwrap();
    println!(">>> {}", rsa_jwe);
    let rsa_jwe = rsa_jwe.chars().skip(5).collect::<String>();
    let (dd, hh) = deserialize_jwe_rsa_2(&rsa_jwe, &rsa_key).unwrap();
    println!("DD: {}", String::from_utf8_lossy(&dd));
    println!("HH: {:?}", hh);

    println!("-------------------------------------------------------------------------------------");
    let rsa_jwe2 = serialize_jwe_rsa_2(b"hello world 003", rsa_public_key).unwrap();
    println!(">>> {}", rsa_jwe2);
    // let rsa_jwe2 = rsa_jwe2.chars().skip(5).collect::<String>();
    let (ddd, hhh) = deserialize_jwe_rsa_2(&rsa_jwe2, &rsa_key).unwrap();
    println!("DDD: {}", String::from_utf8_lossy(&ddd));
    println!("HHH: {:?}", hhh);

    println!("-------------------------------------------------------------------------------------");
    main2();
}

fn main2() {
    let rsa_jwk = r##"{
    "kty":"RSA",
    "e":"AQAB",
    "n":"5xyyPQx8Z7AjVf8Mg4xTE6yN8efPHc0lCdO056R2lzaEQeFwVCbOxFCnmly2-HtE_F_Wd3-B0nxOmODIyC4T
    kLS3hXuflZb-OH73GwYDRmfcvWorACm0hv_a3p8YCuXvZ9aQUPRXwLn1jmAnKJiVRtObZTmmG5TsO-Q-U1DJjKhuP
    --4co9T434y3U9xGIBYAudQ8tn4QSuVInrO2svg4gb9PExLDBn_46yEiLn-q0TzvO-s2rZ0iCpfB0Gji3djQiF-op
    WUjLeGIMLC-gwAOKB4PjlsJBPlIg3pYpRuUEDERIy7kxZ8PIe4Nrfli_sRwMknm9HgQaigu3euYcjxXG9CALTs_vR
    a7lRdpEKQY1ysY_z0bjIk1v-erEyNflQimpDHXGxujVj1EUrYz2diu60acmLSEciThafweAupr_qyKXUutBsc_KPK
    33n8KBIPjl8X7bX2z-dXMKXo312vfPb6iO1ZcoFXG2nkFzwvFUKYFHSGjuZTQKgiaVEhlbq7N-80BlynnkHLYGcbn
    9MtrT8O2Fci1i2ByxyL6B3vB1D5J1VyZ7IBY5AD1GanK2uFmC9nAoFvjTQJt3k2TI_MiPHgb1fZkHu0r-yrf9W_Hr
    PrhBTp5wbepRSC6hs-yTykLJKSE5CD43KbjoW5GCqOkkQMnVjvSY4FpAdTj8Qt7kk"
    }"##;
    let rsa_jwk = rsa_jwk.replace(" ", "");
    let rsa_jwk = rsa_jwk.replace("\r", "");
    let rsa_jwk = rsa_jwk.replace("\n", "");

    println!("{}", rsa_jwk);
    let rsa: Rsa = serde_json::from_str(&rsa_jwk).unwrap();

    let rsa_public_key = rsa::RsaPublicKey::try_from(rsa).unwrap();
    // println!("{:?}", rsa_public_key);

    let mut r = ThreadRng::default();
    let enc = rsa_public_key.encrypt(&mut r, Pkcs1v15Encrypt, b"aaaaaaaa").unwrap();
    println!("{}", STANDARD.encode(&enc));

    let enc2 = rsa_public_key.encrypt(&mut r, Oaep::new::<Sha256>(), b"").unwrap();
    println!("{}", STANDARD.encode(&enc2));
}
