use fastly::http::header;
use fastly::{Error, Request, Response};
use base64::{Engine as _, engine::general_purpose};


/// The name of a backend server associated with this service.
const BACKEND_NAME: &str = "origin_0";

// Fastly only supports URL size up to 8K
// Base64 encoding will increase the body size by 30% and
// we want to leave some buffer, so set the limit to 4K
const MAX_BODY_CONVERT_SIZE: usize = 4 * 1024;

#[fastly::main]
fn main(mut req: Request) -> Result<Response, Error> {
    log_fastly::init_simple("my_log", log::LevelFilter::Info);

    // Make any desired changes to the client request
    req.set_header(header::HOST, "httpbin.org");

    let content_length: usize = get_req_content_length(&req);

    if content_length > MAX_BODY_CONVERT_SIZE || content_length == 0 {
        // Body is too big or content length is 0, not converting will be performed
        return Ok(req.send(BACKEND_NAME)?);
    }

    // Get the base64 encoded body string
    //let body_encoded64 = base64::engine(&req.take_body_bytes(), base64::URL_SAFE_NO_PAD);
    let body_encoded64 = general_purpose::URL_SAFE_NO_PAD.encode(&req.take_body_bytes());

    // Appened the post data as a query parameter
    req.get_url_mut()
        .query_pairs_mut()
        .append_pair("postdata", &body_encoded64)
        .append_pair("method", "GET");
        log::info!("new_req URL is {}", req.get_url());

    // Send the request to backend
    Ok(req.send(BACKEND_NAME)?)
}

/// Get content length of body of the request
fn get_req_content_length(req: &Request) -> usize {
    match req.get_header(header::CONTENT_LENGTH) {
        Some(value) => {
            if let Ok(cl_str) = value.to_str() {
                cl_str.parse().unwrap_or(0)
            } else {
                0
            }
        }
        None => 0,
    }
}