extern crate cfg_if;
extern crate wasm_bindgen;
extern crate base64;
// use rand::Rng;
// use std::convert::{TryInto};
use cfg_if;
use *;
use ;
// use rand::{thread_rng, Rng};
// use rand::rngs::OsRng;
// use noah_x25519_dalek::x25519;
// use noah_x25519_dalek::StaticSecret;
// use noah_x25519_dalek::PublicKey;
use Uuid;
// use cosmian_crypto_core::{
// asymmetric_crypto::{curve25519::{X25519KeyPair, X25519PublicKey, X25519PrivateKey}, DhKeyPair},
// kdf,
// reexport::rand_core::SeedableRng,
// symmetric_crypto::{aes_256_gcm_pure::Aes256GcmCrypto, Dem, SymKey, key::Key},
// CsRng, KeyTrait,
// };
// use passwords::PasswordGenerator;
use JsValue;
// use serde_wasm_bindgen::to_value;
use ;
use RngCore;
// use js_sys::{ArrayBuffer, Float32Array, DataView};
cfg_if!
// #[wasm_bindgen]
// extern "C" {
// fn alert(s: &str);
// }
// #[wasm_bindgen]
// pub fn new_chat_id() -> String {
// let pg = PasswordGenerator {
// length: 17,
// numbers: true,
// lowercase_letters: true,
// uppercase_letters: true,
// symbols: true,
// spaces: false,
// exclude_similar_characters: false,
// strict: true,
// };
// let password_result = pg.generate_one().unwrap();
// // Convert the Vec<String> to a JavaScript Array
// // let array = to_value(&password_result).map_err(JsValue::from)?;
// password_result
// }
// #[wasm_bindgen]
// pub fn password() -> String {
// // alert(&format!("Hello,{}!", name));
// const CHARSET: &[u8] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\
// abcdefghijklmnopqrstuvwxyz\
// 0123456789){}[](*&^%$#@!~".as_bytes();
// // let mut rng = rand::thread_rng();
// let password_result: String = (0..60)
// .map(|_| {
// let idx = thread_rng().gen_range(0..CHARSET.len());
// CHARSET[idx] as char
// })
// .collect();
// return password_result
// }
// #[wasm_bindgen]
// pub fn generate_public_key() -> String {
// // let rng = rand::thread_rng();
// // let rng = rand::thread_rng();
// // let mut rng = OsRng;
// let ali_secret = StaticSecret::new(&mut OsRng);
// let sec_bytes = ali_secret.to_bytes();
// let ali_public = PublicKey::from(&ali_secret);
// let pub_bytes = ali_public.to_bytes();
// let sec_enc = encode(sec_bytes);
// let pub_enc = encode(pub_bytes);
// let vec_pk_sk = vec![sec_enc,pub_enc];
// return vec_pk_sk.iter().cloned().collect::<String>();
// }
// #[wasm_bindgen]
// pub fn generate_shared_secret( main_secret:String, peer_pubkey:String ) -> String{
// let sec_dec:[u8; 32]= (decode(main_secret).unwrap()).try_into().unwrap();
// let pub_dec:[u8; 32]= (decode(peer_pubkey).unwrap()).try_into().unwrap();
// let create_sec = StaticSecret::from(sec_dec).to_bytes();
// let create_pub = PublicKey::from(pub_dec).to_bytes();
// let shared_secret = x25519(create_sec, create_pub);
// // let shared_secret = create_sec.diffie_hellman(&create_pub);
// // let ss_by = shared_secret.as_bytes();
// // let ss_enc = hex::encode(ss_by);
// let ss_enc = hex::encode(shared_secret);
// return ss_enc
// }
// #[wasm_bindgen]
// pub fn generate_pubprv_keys() -> String {
// let mut rng = CsRng::from_entropy();
// let keypair = X25519KeyPair::new(&mut rng);
// let pub_key = keypair.public_key().to_bytes();
// let prv_key = keypair.private_key().to_bytes();
// let pub_str = base64::encode( pub_key).replace("=", "");
// let prv_str = base64::encode( prv_key).replace("=", "");
// return format!("{},{}", pub_str, prv_str);
// }
// #[wasm_bindgen]
// pub fn encrypt_or_decrypt_files(mode: String, public_k:String, private_k:String, file_data: Vec<u8>, additional_data:String) -> Vec<u8> {
// let pub_decoded = base64::decode(public_k).unwrap();
// let prv_decoded = base64::decode(private_k).unwrap();
// let back_pub = X25519PublicKey::try_from_bytes(pub_decoded.as_slice()).expect("Failed to convert public key string to X25519PublicKey");
// let back_other_prv = X25519PrivateKey::try_from_bytes(prv_decoded.as_slice()).expect("Failed to convert private key string to X25519PrivateKey");
// let shared_sec = &back_pub * &back_other_prv;
// let additional_data_bytes = Some(additional_data.as_bytes());
// const KEY_DERIVATION_INFO: &[u8] = b"Curve25519 KDF derivation";
// const KEY_LENGTH: usize = Aes256GcmCrypto::KEY_LENGTH;
// let symmetric_key: Key<{ KEY_LENGTH }> = SymKey::<KEY_LENGTH>::from_bytes(kdf!(
// KEY_LENGTH,
// &shared_sec.to_bytes(),
// KEY_DERIVATION_INFO
// ));
// match mode.as_ref() {
// "encrypt" => {
// let mut rng = CsRng::from_entropy();
// // let mut result = Vec::new();
// // let chunk_size = 10 * 1024 * 1024; // 1 MB chunk size
// // for chunk in file_data.chunks(chunk_size) {
// let c = Aes256GcmCrypto::encrypt(&mut rng, &symmetric_key, &file_data, additional_data_bytes).unwrap();
// // result.extend(c);
// // }
// // result
// c
// }
// "decrypt" => {
// // let mut result = Vec::new();
// // let chunk_size = 10 * 1024 * 1024; // 1 MB chunk size
// // for chunk in file_data.chunks(chunk_size) {
// let dec = Aes256GcmCrypto::decrypt(&symmetric_key, &file_data, additional_data_bytes).unwrap();
// // result.extend(dec);
// // }
// // result
// dec
// }
// _ => panic!("Invalid mode"),
// }
// }
// pub fn encrypt_or_decrypt_files_testing(
// mode: &str,
// key_k: &str,
// file_data: &[u8],
// ) -> Result<Vec<u8>, JsValue> {
// encrypt_or_decrypt_files2(mode.to_string(), key_k.to_string(), file_data.to_vec())
// }
// #[cfg(test)]
// mod tests {
// use super::*;
// #[test]
// fn test_encrypt_and_decrypt() {
// let key = Aes256Gcm::generate_key(&mut OsRng);
// let encoded_key = base64::encode(&key);
// let plaintext = b"Testing encryption and decryption plus 1";
// // Test encryption
// let encrypted_data = encrypt_or_decrypt_files_testing("encrypt", &encoded_key, plaintext).unwrap();
// // Test decryption
// let decrypted_data = encrypt_or_decrypt_files_testing("decrypt", &encoded_key, &encrypted_data).unwrap();
// // Convert decrypted_data to a string and print it
// let decrypted_string = String::from_utf8(decrypted_data.clone()).unwrap();
// println!("Decrypted data: {}", decrypted_string);
// assert_eq!(plaintext.to_vec(), decrypted_data);
// }
// }