use std::{ops::Deref, time::SystemTime};
use anyhow::Result;
use aws_sigv4::http_request::{
sign, Error, SignableBody, SignableRequest, SigningParams, SigningSettings,
};
use aws_smithy_checksums::http::SHA_256_HEADER_NAME;
use http::{header::AUTHORIZATION, Request};
use hyper::{body, Body};
use crate::{
amz_canonical_request::header::{X_AMZ_CONTENT_SHA_256, X_AMZ_DATE, X_AMZ_SECURITY_TOKEN},
type_alias::{AmzSignParams, HttpRequest},
};
pub async fn sign_with_actual_key(
mut req: HttpRequest,
params: AmzSignParams,
) -> Result<HttpRequest> {
let checksum = req.headers().get(X_AMZ_CONTENT_SHA_256).unwrap().clone();
req.headers_mut().remove(X_AMZ_DATE);
req.headers_mut().remove(X_AMZ_CONTENT_SHA_256);
req.headers_mut().remove(X_AMZ_SECURITY_TOKEN);
req.headers_mut().remove(AUTHORIZATION);
let (p, b) = req.into_parts();
let bytes = body::to_bytes(b).await?;
let mut byte_req = Request::from_parts(p, bytes);
let signing_settings = SigningSettings::default();
let signing_params = SigningParams::builder()
.access_key(params.access_key)
.secret_key(params.secret_key)
.region(params.region)
.service_name(params.service)
.time(SystemTime::now())
.settings(signing_settings)
.build()?;
let signable_request = SignableRequest::from(&byte_req);
let (signing_instructions, _signature) = sign(signable_request, &signing_params)
.unwrap()
.into_parts();
signing_instructions.apply_to_request(&mut byte_req);
let (p, b) = byte_req.into_parts();
req = Request::from_parts(p, Body::from(b));
req.headers_mut().insert(X_AMZ_CONTENT_SHA_256, checksum);
Ok(req)
}