extern crate hyper;

use hyper::server::Request;
use hyper::uri::RequestUri;

use std::fs::File;
use std::io::prelude::Read;
use std::path::Path;

/// Open up a file and call the callback F on it, producing a
/// value of type A. If the file does not exist, then return
/// the default value.
///
/// # Examples
///
/// ```
/// let str = with_file("file_one",
///                     "default".to_string(),
///                     |str| str);
/// let num = with_file("file_two",
///                     42,
///                     |str| str.parse::<u32>());
/// ```
pub fn with_file<A, F>(path: &Path, default: A, callback: F) -> A
    where F: FnOnce(String) -> A + 'static {
    match File::open(path) {
        Ok(mut f)  => {
            let mut s = String::new();
            match f.read_to_string(&mut s) {
                Ok(_) => callback(s.trim().to_string()),
                Err(_) => default,
            }
        },
        Err(_) => default,
    }
}

/// Get the absolute path of a URI, if possible.
pub fn path_for<'a>(req: &'a Request) -> Option<String> {
    if let RequestUri::AbsolutePath(ref s) = req.uri {
        Some(s.to_string())
    } else if let RequestUri::AbsoluteUri(ref url) = req.uri {
        url.serialize_path()
    } else {
        None
    }
}

pub fn domain_for<'a>(req: &'a Request) -> Option<&'a str> {
    if let RequestUri::AbsoluteUri(ref url) = req.uri {
        url.domain()
    } else {
        None
    }
}
