use dat::crypt::CryptAlgorithm::{AES128GCMN, AES256GCMN};
use dat::dat_bank::DatBank;
use dat::dat_key::DatKey;
use dat::error::DatError;
use dat::sign::SignAlgorithm::{P256, P384, P521};
use dat::util::now_unix_timestamp;
use rand::RngExt;

fn rand_string() -> String {
    let mut rng = rand::rng();
    (0..100).map(|_| { rng.sample(rand::distr::Alphanumeric) as char }).collect()
}

fn gen_keys(store: &DatBank<i64>) -> Result<(), DatError> {
    let sign_alg_arr = [P256, P384, P521];
    let crypt_alg_arr = [AES128GCMN, AES256GCMN];
    let mut keys: Vec<DatKey<i64>> = vec![];
    let now = now_unix_timestamp();
    let mut i = 0;
    sign_alg_arr.iter().for_each(|sign_alg| {
        crypt_alg_arr.iter().for_each(|crypt_alg| {
            (1..5).for_each(|_| {
                let kid = i;
                i += 1;
                keys.push(DatKey::generate(kid, *sign_alg, *crypt_alg, now - 10, now + 600, 60).unwrap());
            });
        });
    });
    store.import_keys(keys, false)?;
    Ok(())
}

#[test]
fn test() {
    let bank = DatBank::<i64>::new();

    gen_keys(&bank).unwrap();
    assert!(gen_keys(&bank).is_ok());

    // get all keys
    let dat_list = bank.export_keys().iter().map(|key| {
        let act = key.clone().active().unwrap();
        act.to_dat(&rand_string(), &rand_string()).unwrap()
    }).collect::<Vec<String>>();

    // copy keys
    let keys = bank.export_keys_format(false);
    let bank2: DatBank<i64> = DatBank::new();
    bank2.import_keys_format(keys, true).unwrap();

    // verify
    for dat in dat_list.iter() {
        let (plain, secure) = bank2.to_payload_verify(&dat).unwrap();
        println!("bank plain:{}.secure:{}", plain, secure);
    }
}