use hmac::{Hmac, Mac};
use sha1::Sha1;
use base64::{prelude::BASE64_STANDARD, Engine};

/// Hmac-Sha1签名工具
#[derive(Debug)]
pub struct HmacSha1();

impl HmacSha1 {

    pub fn sign_to_bytes(&self, data: &str, key: &str) -> Vec<u8> {
        let key = key.as_bytes();
        let data = data.as_bytes();
        let mut hmac = Hmac::<Sha1>::new_from_slice(key).expect("HMAC can take key of any size");
        hmac.update(data);
        let result = hmac.finalize();
        let hmac_bytes = result.into_bytes();
        hmac_bytes.to_vec()
    }

    pub fn sign_to_base64string(&self, data: &str, key: &str) -> String {
        let bytes = self.sign_to_bytes(data, key);
        let base64 = BASE64_STANDARD.encode(bytes);
        base64
    }

    pub fn header_string_to_sign(&self, http_verb: &str, content_md5: &str, content_type: &str, date: &str, canonicalized_headers: &str, canonicalized_resource: &str) -> String{
        let string_to_sign = format!("{}\n{}\n{}\n{}\n{}{}", http_verb, content_md5, content_type, date, canonicalized_headers, canonicalized_resource);
        string_to_sign
    }

    pub fn url_string_to_sign(&self, http_verb: &str, content_md5: &str, content_type: &str, expires: &str, canonicalized_headers: &str, canonicalized_resource: &str) -> String{
        format!("{}\n{}\n{}\n{}\n{}{}", http_verb, content_md5, content_type, expires, canonicalized_headers, canonicalized_resource)
    }

}