use cookie::{Cookie, CookieJar};
use fastly::http::{header, HeaderValue};
use fastly::{Error, Request, Response};
use log::LevelFilter::Info;

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

    if let Some(mut req_cookie_jar) = req
        .get_header(header::COOKIE)
        .and_then(|h| parse_cookies_to_jar(h).ok())
    {
        log::info!(
            "The value of myCookie is {}",
            req_cookie_jar
                .get("myCookie")
                .map(|c| c.value())
                .unwrap_or_default()
        );

        // Remove a cookie from the request
        req_cookie_jar.remove(Cookie::named("myCookie"));

        // rebuild `cookie` header
        let new_hdr = req_cookie_jar
            .iter()
            .map(ToString::to_string)
            .collect::<Vec<_>>()
            .join("; ");

        req.set_header(header::COOKIE, new_hdr);
    } else {
        log::warn!("Header cookie absent or could not be parsed");
    }

    log::info!(
        "New Cookie header is {}",
        req.get_header(header::COOKIE)
            .and_then(|h| h.to_str().ok())
            .unwrap_or_default(),
    );

    // Remove all cookies from the request
    req.remove_header(header::COOKIE);
    
    let mut beresp = req.send("origin_0")?;
    
    // Set a cookie in response
    beresp.set_header(header::SET_COOKIE, "myCookie=foo; path=/; max-age=60");

    // You can set multiple cookies in one response
    beresp.append_header(header::SET_COOKIE, "mySecondCookie=bar; httpOnly");

    // It is usually a good idea to prevent downstream caching of
    // responses that set cookies
    beresp.set_header(header::CACHE_CONTROL, "no-store, private");
    
    Ok(beresp)
}

fn parse_cookies_to_jar(value: &HeaderValue) -> Result<CookieJar, Error> {
    let mut jar = CookieJar::new();
    for cookie in value.to_str()?.split(';').map(Cookie::parse) {
        jar.add_original(cookie?.into_owned());
    }
    Ok(jar)
}