#![cfg(feature = "http")]

use crate::types::Document;
use http::{header::CONTENT_TYPE, HeaderValue, Response};

pub type Body = Vec<u8>;

/// Converts [this response][::http::Response] into a [MF2 document][microformats::types::Document].
///
/// # Errors
///
/// This function will return an error if it could not detect the content type of this request or
/// fails to convert it into a MF2 document.
pub fn to_mf2_document(resp: Response<Body>, page_url: &str) -> Result<Document, crate::Error> {
    let ct_header = resp
        .headers()
        .get(CONTENT_TYPE)
        .cloned()
        .unwrap_or_else(|| HeaderValue::from_static("text/html"))
        .as_ref()
        .to_vec();

    let ct_header_str = String::from_utf8(ct_header)?;

    if ct_header_str.starts_with("application/mf2+json") {
        to_json(resp)
            .and_then(|v| Ok(serde_json::from_value(v).map_err(microformats_types::Error::from)?))
    } else {
        to_string(resp).and_then(|str| crate::from_html(&str, &page_url.parse()?))
    }
}

fn to_string(resp: Response<Body>) -> Result<String, crate::Error> {
    Ok(String::from_utf8(resp.into_body())?)
}

fn to_json(resp: Response<Body>) -> Result<serde_json::Value, crate::Error> {
    Ok(serde_json::from_slice(resp.into_body().as_slice())
        .map_err(microformats_types::Error::from)?)
}
