use crate::error::DatError;
use base64::engine::general_purpose;
use base64::Engine;
use std::time::SystemTime;

const BASE64_URL: &general_purpose::GeneralPurpose = &general_purpose::URL_SAFE_NO_PAD;

#[inline]
pub fn encode_base64_url<T: AsRef<[u8]>>(b: T) -> String {
    BASE64_URL.encode(b)
}

#[inline]
pub fn encode_base64_url_out<T: AsRef<[u8]>>(b: T, out: &mut String) {
    BASE64_URL.encode_string(b, out)
}

#[inline]
pub fn decode_base64_url<T: AsRef<[u8]>>(b64: T) -> Result<Vec<u8>, DatError> {
    Ok(BASE64_URL.decode(&b64)?)
}

#[inline]
pub fn decode_base64_url_out<T: AsRef<[u8]>>(b64: T, out: &mut Vec<u8>) -> Result<(), DatError> {
    Ok(BASE64_URL.decode_vec(&b64, out)?)
}

#[inline]
pub fn decode_base64_url_out_str<T: AsRef<[u8]>>(b64: T, out: &mut String) -> Result<(), DatError> {
    unsafe {
        Ok(BASE64_URL.decode_vec(&b64, out.as_mut_vec())?)
    }
}

#[inline]
pub fn now_unix_timestamp() -> u64 {
    // unwrap() 으로 무시 : 시스템이 1970년 이전으로 발생해 음수 발생시 나는 오류로 무시
    SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs()
}

#[inline]
pub fn to_utf8(vec: Vec<u8>) -> Result<String, DatError> {
    Ok(String::from_utf8(vec)?)
}

pub fn to_hex_u64(value: u64) -> String {
    format!("{:x}", value)
}
