// Copyright 2020 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use std::collections::HashMap;
use std::fmt;
use std::io::{self, BufRead, BufReader, BufWriter, Cursor, Read, Write};
use std::num::ParseIntError;
use std::str::FromStr;

use sys_util::{debug, error};
use tiny_http::{Header, Method};

use crate::io_adapters::{ChunkedWriter, CompleteReader, LoggingReader};
use crate::usb_connector::UsbConnection;
use crate::util::read_until_delimiter;

// Minimum Request body size, in bytes, before we switch to forwarding requests
// using a chunked Transfer-Encoding.
const CHUNKED_THRESHOLD: usize = 1 << 15;
const VERSION: Option<&'static str> = option_env!("CARGO_PKG_VERSION");

#[derive(Debug)]
pub enum Error {
    DuplicateBodyReader,
    EmptyField(String),
    ForwardRequestBody(io::Error),
    MalformedRequest,
    MalformedContentLength(String, ParseIntError),
    ParseResponse(httparse::Error),
    ReadResponseHeader(io::Error),
    WriteRequestHeader(io::Error),
    WriteResponse(io::Error),
}

impl std::error::Error for Error {}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use Error::*;
        match self {
            DuplicateBodyReader => write!(f, "Attempted to call body_reader() multiple times."),
            EmptyField(field) => write!(f, "HTTP Response field {} was unexpectedly empty", field),
            ForwardRequestBody(err) => write!(f, "Forwarding request body failed: {}", err),
            MalformedRequest => write!(f, "HTTP request is malformed"),
            MalformedContentLength(value, err) => write!(
                f,
                "Failed to parse response Content-Length '{}': {}",
                value, err
            ),
            ParseResponse(err) => write!(f, "Failed to parse HTTP Response header: {}", err),
            ReadResponseHeader(err) => write!(f, "Reading response header failed: {}", err),
            WriteRequestHeader(err) => write!(f, "Writing request header failed: {}", err),
            WriteResponse(err) => write!(f, "Responding to request failed: {}", err),
        }
    }
}

type Result<T> = std::result::Result<T, Error>;

#[derive(Copy, Clone, PartialEq)]
enum BodyLength {
    Chunked,
    Exactly(usize),
}

struct ResponseReader<R: BufRead + Sized> {
    verbose_log: bool,
    reader: R,
    body_length: BodyLength,
    header_was_read: bool,
    created_body_reader: bool,
}

impl<R> ResponseReader<R>
where
    R: BufRead + Sized,
{
    fn new(verbose_log: bool, reader: R) -> ResponseReader<R> {
        ResponseReader {
            verbose_log,
            reader,
            // Assume body is empty unless we see a header to the contrary.
            body_length: BodyLength::Exactly(0),
            header_was_read: false,
            created_body_reader: false,
        }
    }

    fn read_header(&mut self) -> Result<(tiny_http::StatusCode, Vec<Header>)> {
        self.header_was_read = true;

        let buf = read_until_delimiter(&mut self.reader, b"\r\n\r\n")
            .map_err(Error::ReadResponseHeader)?;
        let mut headers = [httparse::EMPTY_HEADER; 32];
        let mut response = httparse::Response::new(&mut headers);
        let (status, headers) = match response.parse(&buf).map_err(Error::ParseResponse)? {
            httparse::Status::Complete(i) if i == buf.len() => {
                let code = response
                    .code
                    .ok_or_else(|| Error::EmptyField("code".to_owned()))?;
                let status = tiny_http::StatusCode::from(code);
                let version = response
                    .version
                    .ok_or_else(|| Error::EmptyField("version".to_owned()))?;
                debug!(
                    "> HTTP/1.{} {} {}",
                    version,
                    code,
                    status.default_reason_phrase()
                );
                let mut parsed_headers = Vec::new();
                for header in headers.iter().take_while(|&&h| h != httparse::EMPTY_HEADER) {
                    if let Ok(h) = Header::from_bytes(header.name, header.value) {
                        if self.verbose_log {
                            debug!("  {}: {}", h.field, h.value);
                        }
                        parsed_headers.push(h);
                    } else {
                        error!(
                            "Ignoring malformed header {}:{:#?}",
                            header.name, header.value
                        );
                    }
                }
                (status, parsed_headers)
            }
            _ => return Err(Error::MalformedRequest),
        };

        // Determine the size of the body content.
        for header in headers.iter() {
            if header.field.equiv("Content-Length") {
                let length = usize::from_str(header.value.as_str()).map_err(|e| {
                    Error::MalformedContentLength(header.value.as_str().to_string(), e)
                })?;
                self.body_length = BodyLength::Exactly(length);
                break;
            }

            if header.field.equiv("Transfer-Encoding") {
                self.body_length = BodyLength::Chunked;
                break;
            }
        }

        Ok((status, headers))
    }

    fn body_reader<'r>(&'r mut self) -> Result<Box<dyn Read + 'r>> {
        if self.created_body_reader {
            return Err(Error::DuplicateBodyReader);
        }

        self.created_body_reader = true;
        match self.body_length {
            BodyLength::Exactly(length) => {
                let reader = (&mut self.reader).take(length as u64);
                Ok(Box::new(CompleteReader::new(reader)))
            }
            BodyLength::Chunked => {
                let reader = chunked_transfer::Decoder::new(&mut self.reader);
                Ok(Box::new(CompleteReader::new(reader)))
            }
        }
    }
}

impl<R> Drop for ResponseReader<R>
where
    R: BufRead,
{
    fn drop(&mut self) {
        if !self.created_body_reader {
            debug!("Draining in drop");
            if !self.header_was_read {
                // Read header to figure out how long the body is.
                let _ = self.read_header();
            }

            // Create a body reader which will totally read the response on drop.
            let _ = self.body_reader();
        }
    }
}

fn is_end_to_end(header: &Header) -> bool {
    match header.field.as_str().as_str() {
        "Connection"
        | "Expect" // Technically end-to-end, but we want to filter it.
        | "Keep-Alive"
        | "Proxy-Authenticate"
        | "Proxy-Authorization"
        | "TE"
        | "Trailers"
        | "Transfer-Encoding"
        | "Upgrade" => false,
        _ => true,
    }
}

fn supports_request_body(method: &Method) -> bool {
    match method {
        Method::Get | Method::Head | Method::Delete | Method::Options | Method::Trace => false,
        _ => true,
    }
}

#[derive(Eq)]
struct HeaderField {
    value: String,
}

impl HeaderField {
    fn new(value: &str) -> Self {
        Self {
            value: value.to_string(),
        }
    }
}

impl std::cmp::PartialEq for HeaderField {
    fn eq(&self, other: &Self) -> bool {
        self.value.eq_ignore_ascii_case(&other.value)
    }
}

impl std::hash::Hash for HeaderField {
    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
        self.value.to_ascii_lowercase().hash(state);
    }
}

impl fmt::Display for HeaderField {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "{}", self.value)
    }
}

struct Headers {
    values: HashMap<HeaderField, Vec<String>>,
}

impl Headers {
    pub fn new() -> Self {
        Headers {
            values: HashMap::new(),
        }
    }

    pub fn delete_header(&mut self, k: &str) -> Option<Vec<String>> {
        self.values.remove(&HeaderField::new(k))
    }

    pub fn add_header(&mut self, k: &str, v: &str) {
        self.values
            .entry(HeaderField::new(k))
            .or_default()
            .push(v.to_string());
    }

    pub fn has_header(&self, k: &str) -> bool {
        self.values.contains_key(&HeaderField::new(k))
    }
}

struct Request {
    method: String,
    url: String,
    headers: Headers,
    body_length: BodyLength,
    forwarded_body_length: BodyLength,
}

// Converts a tiny_http::Request into our internal Request format.
// Filter out Hop-by-hop headers and add Content-Length or Transfer-Encoding
// headers as needed.
fn rewrite_request(request: &tiny_http::Request) -> Request {
    let mut headers = Headers::new();
    // If the incoming request specifies a Transfer-Encoding, it must be chunked.
    let request_is_chunked = request
        .headers()
        .iter()
        .any(|h| h.field.equiv("Transfer-Encoding"));

    for header in request.headers().iter().filter(|&h| is_end_to_end(h)) {
        // Call as_str() twice for conversion from header name to &AsciiStr to &str.
        headers.add_header(header.field.as_str().as_str(), header.value.as_str());
    }

    let body_length = if !supports_request_body(request.method()) {
        BodyLength::Exactly(0)
    } else if request_is_chunked {
        BodyLength::Chunked
    } else if let Some(length) = request.body_length() {
        BodyLength::Exactly(length)
    } else {
        BodyLength::Exactly(0)
    };

    headers.delete_header("User-Agent");
    let user_agent = format!("ippusb_bridge/{}", VERSION.unwrap_or("unknown"));
    headers.add_header("User-Agent", &user_agent);

    // If the request body is relatively small, don't use a chunked encoding for
    // the proxied request.
    let forwarded_body_length = match body_length {
        BodyLength::Exactly(length) if length < CHUNKED_THRESHOLD => body_length,
        _ => BodyLength::Chunked,
    };

    if forwarded_body_length == BodyLength::Chunked {
        // Content-Length and chunked encoding are mutually exclusive.
        // We don't need to delete any existing Transfer-Encoding since it's a
        // Hop-by-hop header and is already filtered out above.
        headers.delete_header("Content-Length");
        headers.add_header("Transfer-Encoding", "chunked");
    } else if !headers.has_header("Content-Length") {
        headers.add_header("Content-Length", "0");
    }

    Request {
        method: request.method().to_string(),
        url: request.url().to_string(),
        headers,
        body_length,
        forwarded_body_length,
    }
}

fn serialize_request_header(
    verbose_log: bool,
    request: &Request,
    writer: &mut dyn Write,
) -> io::Result<()> {
    write!(writer, "{} {} HTTP/1.1\r\n", request.method, request.url)?;
    if verbose_log {
        debug!("{} {} HTTP/1.1\\r\n", request.method, request.url);
    }
    for (field, values) in request.headers.values.iter() {
        for value in values.iter() {
            write!(writer, "{}: {}\r\n", field, value)?;
            if verbose_log {
                debug!("  {}: {}\\r", field, value);
            }
        }
    }

    write!(writer, "\r\n")?;
    if verbose_log {
        debug!("\\r");
    }
    writer.flush()
}

pub fn handle_request(
    verbose_log: bool,
    usb: UsbConnection,
    mut request: tiny_http::Request,
) -> Result<()> {
    debug!(
        "< {} {} HTTP/1.{}",
        request.method(),
        request.url(),
        request.http_version().1
    );

    // Filter out headers that should not be forwarded, and update Content-Length and
    // Transfer-Encoding headers based on how the body (if any) will be transferred.
    let new_request = rewrite_request(&request);

    let mut logging_reader = LoggingReader::new(request.as_reader(), "client");
    let mut request_body: Box<dyn Read> = match new_request.forwarded_body_length {
        BodyLength::Exactly(length) => {
            // If we're not using chunked, we must have the entire request body before beginning to
            // forward the request. If we didn't and the client were to drop in the middle of
            // forwarding a request, we would have no way of cleanly terminating the connection.
            let mut buf = Vec::with_capacity(length);
            io::copy(&mut logging_reader, &mut buf).map_err(Error::ForwardRequestBody)?;
            Box::new(Cursor::new(buf))
        }
        _ => Box::new(logging_reader),
    };

    let mut usb_writer = BufWriter::new(&usb);
    // Write the modified request header to the printer.
    serialize_request_header(verbose_log, &new_request, &mut usb_writer)
        .map_err(Error::WriteRequestHeader)?;

    // Now that we have written data to the printer, we must ensure that we read
    // a complete HTTP response from the printer. Otherwise, that data may
    // remain in the printer's buffers and be sent to some other client.
    // ResponseReader ensures that this happens internally.
    let usb_reader = BufReader::new(LoggingReader::new(&usb, "printer"));
    let mut response_reader = ResponseReader::new(verbose_log, usb_reader);

    if new_request.body_length != BodyLength::Exactly(0) {
        debug!("* Forwarding client request body");
        let mut writer: Box<dyn Write> = match new_request.forwarded_body_length {
            BodyLength::Chunked => Box::new(ChunkedWriter::new(usb_writer)),
            _ => Box::new(usb_writer),
        };
        io::copy(&mut request_body, &mut writer).map_err(Error::ForwardRequestBody)?;
        writer.flush().map_err(Error::ForwardRequestBody)?;
    }
    drop(request_body);

    debug!("* Reading printer response header");
    let (status, headers) = response_reader.read_header()?;

    debug!("* Forwarding printer response body");
    let body_reader = response_reader.body_reader()?;
    let response = tiny_http::Response::new(status, headers, body_reader, None, None);
    request.respond(response).map_err(Error::WriteResponse)?;

    debug!("* Finished processing request");
    Ok(())
}
