use std::sync::Arc;

use crate::msgs::squic::{SUNNY_QUIC_AUTH_LEN, SunnyCredential};

pub mod inbound;
pub mod outbound;

#[cfg(any(feature = "sunnyquic-gm-quic", feature = "sunnyquic-noq"))]
pub(crate) mod dynamic_cert;

#[cfg(all(feature = "sunnyquic-gm-quic", not(feature = "sunnyquic-noq")))]
mod gm_quic_wrapper;
#[cfg(all(feature = "sunnyquic-gm-quic", not(feature = "sunnyquic-noq")))]
pub use gm_quic_wrapper::{Connection, EndClient, EndServer};

#[cfg(feature = "sunnyquic-noq")]
mod noq_wrapper;
#[cfg(feature = "sunnyquic-noq")]
pub use noq_wrapper::{Connection, EndClient, EndServer};

#[cfg(all(feature = "ring", not(feature = "aws-lc-rs")))]
use ring::digest;

#[cfg(feature = "aws-lc-rs")]
use aws_lc_rs::digest;

#[cfg(all(not(feature = "sunnyquic-noq"), not(feature = "sunnyquic-gm-quic")))]
mod unimplemented;
#[cfg(all(not(feature = "sunnyquic-noq"), not(feature = "sunnyquic-gm-quic")))]
pub use unimplemented::{Connection, EndClient, EndServer};

/// Generate sunnyquic user hash from username and password
/// The hash is generated by SHA256(username:password)
pub fn gen_sunny_user_hash(username: &str, password: &str) -> SunnyCredential {
    let hash_in = username.to_string() + ":" + password;
    let hash_bytes_input = hash_in.into_bytes();
    let hash_bytes = {
        let out = digest::digest(&digest::SHA256, hash_bytes_input.as_ref());
        let mut arr = [0u8; SUNNY_QUIC_AUTH_LEN];
        let len = arr.len().min(out.as_ref().len());
        arr[..len].copy_from_slice(&out.as_ref()[..len]);
        arr
    };
    Arc::new(hash_bytes)
}
