use fastly::http::{header, StatusCode};
use fastly::{Error, Request, Response};

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

/// The name of google cloud storage bucket name
const BUCKET_NAME: &str = "betts-gcp-gcs-fastly-tutorial";

#[fastly::main]
fn main(mut req: Request) -> Result<Response, Error> {
    // Set the host header for backend access
    // Not needed if Overide host configuration of backend is set
    req.set_header(header::HOST, "storage.googleapis.com");

    // Get a clone of original request in case we need a retry later
    let mut retry_req = req.clone_with_body();

    // Fetch the index page if the request is for a directory
    let path = req.get_path();
    let page = if path.ends_with('/') {
        "index.html"
    } else {
        ""
    };

    // Add bucket name to the request path
    let mut path_with_bucket = format!("/{}{}{}", BUCKET_NAME, path, page);
    req.set_path(&path_with_bucket);

    // Send the request to backend
    let resp = req.send(BACKEND_NAME)?;

    if resp.get_status() == StatusCode::NOT_FOUND && !path_with_bucket.ends_with("/index.html") {
        // Not found, and not already an index page, try again for the directory index
        let orig_path = retry_req.get_path().to_string();

        path_with_bucket = format!("/{}{}/index.html", BUCKET_NAME, &orig_path);
        retry_req.set_path(&path_with_bucket);

        // Send the retry request to backend
        let resp_retry = retry_req.send(BACKEND_NAME)?;

        if resp_retry.get_status() == StatusCode::OK {
            // Retry for a directory page has succeeded, redirect externally to the directory URL.
            let new_location = format!("{}/", orig_path);
            let resp_moved = Response::from_status(StatusCode::MOVED_PERMANENTLY)
                .with_header(header::LOCATION, new_location);
            Ok(resp_moved)
        } else {
            Ok(resp_retry)
        }
    } else {
        Ok(resp)
    }
}