// Copyright (C) 2019, Cloudflare, Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

//! HTTP/3 wire protocol and QPACK implementation.
//!
//! This module provides a high level API for sending and receiving HTTP/3
//! requests and responses on top of the QUIC transport protocol.
//!
//! ## Connection setup
//!
//! HTTP/3 connections require a QUIC transport-layer connection, see
//! [Connection setup] for a full description of the setup process.
//!
//! To use HTTP/3, the QUIC connection must be configured with a suitable
//! Application Layer Protocol Negotiation (ALPN) Protocol ID:
//!
//! ```
//! let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! config.set_application_protos(b"\x05h3-18").unwrap();
//! ```
//!
//! The QUIC handshake is driven by [sending] and [receiving] QUIC packets.
//! Once the handshake has completed, the application should check that HTTP/3
//! was negotiated using the [`application_proto()`] method:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let server_name = "quic.tech";
//! # let scid = [0xba; 16];
//! # let conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();
//! if conn.is_established() && conn.application_proto() == b"h3-18" {
//!     // Handshake completed and HTTP/3 negotiated.
//! }
//! ```
//!
//! The first step in establishing an HTTP/3 connection is creating its
//! configuration object:
//!
//! ```
//! let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! ```
//!
//! HTTP/3 client and server connections are both created using the
//! [`with_transport()`] function, the role is inferred from the type of QUIC
//! connection:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let server_name = "quic.tech";
//! # let scid = [0xba; 16];
//! # let mut conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();
//! # let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! let h3_conn = quiche::h3::Connection::with_transport(&mut conn, &h3_config).unwrap();
//! ```
//!
//! ## Sending a request
//!
//! An HTTP/3 client can send a request by using the connection's
//! [`send_request()`] method to queue request headers; [sending] QUIC packets
//! causes the requests to get sent to the peer:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let server_name = "quic.tech";
//! # let scid = [0xba; 16];
//! # let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! # let mut conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();
//! # let mut h3_conn = quiche::h3::Connection::with_transport(&mut conn, &h3_config).unwrap();
//! let req = vec![
//!     quiche::h3::Header::new(":method", "GET"),
//!     quiche::h3::Header::new(":scheme", "https"),
//!     quiche::h3::Header::new(":authority", "quic.tech"),
//!     quiche::h3::Header::new(":path", "/"),
//!     quiche::h3::Header::new(":user-agent", "quiche"),
//! ];
//!
//! h3_conn.send_request(&mut conn, &req, true).unwrap();
//! ```
//!
//! An HTTP/3 client can send a request with additional body data by using
//! the connection's [`send_body()`] method:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let server_name = "quic.tech";
//! # let scid = [0xba; 16];
//! # let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! # let mut conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();
//! # let mut h3_conn = quiche::h3::Connection::with_transport(&mut conn, &h3_config).unwrap();
//! let req = vec![
//!     quiche::h3::Header::new(":method", "GET"),
//!     quiche::h3::Header::new(":scheme", "https"),
//!     quiche::h3::Header::new(":authority", "quic.tech"),
//!     quiche::h3::Header::new(":path", "/"),
//!     quiche::h3::Header::new(":user-agent", "quiche"),
//! ];
//!
//! let stream_id = h3_conn.send_request(&mut conn, &req, false).unwrap();
//! h3_conn.send_body(&mut conn, stream_id, b"Hello World!", true).unwrap();
//! ```
//!
//! ## Handling requests and responses
//!
//! After [receiving] QUIC packets, HTTP/3 data is processed using the
//! connection's [`poll()`] method. On success, this returns an [`Event`] object
//! and an ID corresponding to the stream where the `Event` originated.
//!
//! An HTTP/3 server uses [`poll()`] to read requests and responds to them using
//! [`send_response()`] and [`send_body()`]:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let scid = [0xba; 16];
//! # let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! # let mut conn = quiche::accept(&scid, None, &mut config).unwrap();
//! # let mut h3_conn = quiche::h3::Connection::with_transport(&mut conn,
//! #                                                       &h3_config).unwrap();
//! loop {
//!     match h3_conn.poll(&mut conn) {
//!         Ok((stream_id, quiche::h3::Event::Headers(headers))) => {
//!             let mut headers = headers.into_iter();
//!
//!             // Look for the request's method.
//!             let method = headers.find(|h| h.name() == ":method").unwrap();
//!
//!             // Look for the request's path.
//!             let path = headers.find(|h| h.name() == ":path").unwrap();
//!
//!             if method.value() == "GET" && path.value() == "/" {
//!                 let resp = vec![
//!                     quiche::h3::Header::new(":status", &200.to_string()),
//!                     quiche::h3::Header::new("server", "quiche"),
//!                 ];
//!
//!                 h3_conn.send_response(&mut conn, stream_id, &resp, false).unwrap();
//!                 h3_conn.send_body(&mut conn, stream_id, b"Hello World!", true).unwrap();
//!             }
//!         },
//!
//!         Ok((stream_id, quiche::h3::Event::Data(data))) => {
//!             // Request body data, handle it.
//!             # return;
//!         },
//!
//!         Err(quiche::h3::Error::Done) => {
//!             // Done reading.
//!             break;
//!         },
//!
//!         Err(e) => {
//!             // An error occurred, handle it.
//!             break;
//!         },
//!     }
//! }
//! ```
//!
//! An HTTP/3 client uses [`poll()`] to read responses:
//!
//! ```no_run
//! # let mut config = quiche::Config::new(quiche::VERSION_DRAFT19).unwrap();
//! # config.set_application_protos(b"\x05h3-18").unwrap();
//! # let server_name = "quic.tech";
//! # let scid = [0xba; 16];
//! # let h3_config = quiche::h3::Config::new(0, 1024, 0, 0).unwrap();
//! # let mut conn = quiche::connect(Some(&server_name), &scid, &mut config).unwrap();
//! # let mut h3_conn = quiche::h3::Connection::with_transport(&mut conn,
//! #                                                       &h3_config).unwrap();
//! loop {
//!     match h3_conn.poll(&mut conn) {
//!         Ok((stream_id, quiche::h3::Event::Headers(headers))) => {
//!             let status = headers.iter().find(|h| h.name() == ":status").unwrap();
//!             println!("Received {} response on stream {}",
//!                      status.value(), stream_id);
//!         },
//!
//!         Ok((stream_id, quiche::h3::Event::Data(data))) => {
//!             println!("Received {} bytes of payload on stream {}",
//!                      data.len(), stream_id);
//!         },
//!
//!         Err(quiche::h3::Error::Done) => {
//!             // Done reading.
//!             break;
//!         },
//!
//!         Err(e) => {
//!             // An error occurred, handle it.
//!             break;
//!         },
//!     }
//! }
//! ```
//!
//! ## Detecting end of stream
//!
//! HTTP/3 request and response exchanges may consist of several HEADERS and
//! DATA frames. Calling [`poll()`] repeatedly will generate an [`Event`] for
//! each. The QUIC connection's [`stream_finished()`] method can be used to
//! detect if the stream was ended by the peer. Additional HTTP/3 validation
//! can be applied by the application to ensure protocol correctness.
//!
//! [`application_proto()`]: ../struct.Connection.html#method.application_proto
//! [`stream_finished()`]: ../struct.Connection.html#method.stream_finished
//! [Connection setup]: ../index.html#connection-setup
//! [sending]: ../index.html#generating-outgoing-packets
//! [receiving]: ../index.html#handling-incoming-packets
//! [`with_transport()`]: struct.Connection.html#method.with_transport
//! [`poll()`]: struct.Connection.html#method.poll
//! [`Event`]: enum.Event.html
//! [`send_request()`]: struct.Connection.html#method.send_response
//! [`send_response()`]: struct.Connection.html#method.send_response
//! [`send_body()`]: struct.Connection.html#method.send_body

use std::collections::BTreeMap;

use crate::octets;

/// A specialized [`Result`] type for quiche HTTP/3 operations.
///
/// This type is used throughout quiche's HTTP/3 public API for any operation
/// that can produce an error.
///
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
pub type Result<T> = std::result::Result<T, Error>;

/// An HTTP/3 error.
#[derive(Clone, Copy, Debug, PartialEq)]
#[repr(C)]
pub enum Error {
    /// There is no error or no work to do
    Done                 = -1,

    /// The provided buffer is too short.
    BufferTooShort       = -2,

    /// Setting sent in wrong direction.
    WrongSettingDirection = -3,

    /// The server attempted to push content that the client will not accept.
    PushRefused          = -4,

    /// Internal error in the HTTP/3 stack.
    InternalError        = -5,

    /// The server attempted to push something the client already has.
    PushAlreadyInCache   = -6,

    /// The client no longer needs the requested data.
    RequestCancelled     = -7,

    /// The request stream terminated before completing the request.
    IncompleteRequest    = -8,

    /// Forward connection failure for CONNECT target.
    ConnectError         = -9,

    /// Endpoint detected that the peer is exhibiting behavior that causes.
    /// excessive load.
    ExcessiveLoad        = -10,

    /// Operation cannot be served over HTTP/3. Retry over HTTP/1.1.
    VersionFallback      = -11,

    /// Frame received on stream where it is not permitted.
    WrongStream          = -12,

    /// Stream ID, Push ID or Placeholder Id greater that current maximum was.
    /// used
    LimitExceeded        = -13,

    /// Push ID used in two different stream headers.
    DuplicatePush        = -14,

    /// Unknown unidirection stream type.
    UnknownStreamType    = -15,

    /// Too many unidirectional streams of a type were created.
    WrongStreamCount     = -16,

    /// A required critical stream was closed.
    ClosedCriticalStream = -17,

    /// Unidirectional stream type opened at peer that is prohibited.
    WrongStreamDirection = -18,

    /// Inform client that remainder of request is not needed. Used in
    /// STOP_SENDING only.
    EarlyResponse        = -19,

    /// No SETTINGS frame at beginning of control stream.
    MissingSettings      = -20,

    /// A frame was received which is not permitted in the current state.
    UnexpectedFrame      = -21,

    /// Server rejected request without performing any application processing.
    RequestRejected      = -22,

    /// Peer violated protocol requirements in a way that doesn't match a more
    /// specific code.
    GeneralProtocolError = -23,

    /// TODO: malformed frame where last on-wire byte is the frame type.
    MalformedFrame       = -24,

    /// QPACK Header block decompression failure.
    QpackDecompressionFailed = -25,

    /// QPACK encoder stream error.
    QpackEncoderStreamError = -26,

    /// QPACK decoder stream error.
    QpackDecoderStreamError = -27,
}

impl Error {
    pub fn to_wire(self) -> u16 {
        match self {
            Error::Done => 0x0,
            Error::WrongSettingDirection => 0x1,
            Error::PushRefused => 0x2,
            Error::InternalError => 0x3,
            Error::PushAlreadyInCache => 0x4,
            Error::RequestCancelled => 0x5,
            Error::IncompleteRequest => 0x6,
            Error::ConnectError => 0x07,
            Error::ExcessiveLoad => 0x08,
            Error::VersionFallback => 0x09,
            Error::WrongStream => 0xA,
            Error::LimitExceeded => 0xB,
            Error::DuplicatePush => 0xC,
            Error::UnknownStreamType => 0xD,
            Error::WrongStreamCount => 0xE,
            Error::ClosedCriticalStream => 0xF,
            Error::WrongStreamDirection => 0x10,
            Error::EarlyResponse => 0x11,
            Error::MissingSettings => 0x12,
            Error::UnexpectedFrame => 0x13,
            Error::RequestRejected => 0x14,
            Error::GeneralProtocolError => 0xFF,
            Error::MalformedFrame => 0x10,

            Error::QpackDecompressionFailed => 0x20, // TODO: value is TBD
            Error::QpackEncoderStreamError => 0x21,  // TODO: value is TBD
            Error::QpackDecoderStreamError => 0x22,  // TODO: value is TBD
            Error::BufferTooShort => 0x999,
        }
    }

    fn to_c(self) -> libc::ssize_t {
        self as _
    }
}

impl std::fmt::Display for Error {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        write!(f, "{:?}", self)
    }
}

impl std::error::Error for Error {
    fn description(&self) -> &str {
        // TODO: fill this
        ""
    }

    fn cause(&self) -> Option<&std::error::Error> {
        None
    }
}

impl std::convert::From<super::Error> for Error {
    fn from(err: super::Error) -> Self {
        match err {
            super::Error::Done => Error::Done,
            super::Error::BufferTooShort => Error::BufferTooShort,
            _ => Error::GeneralProtocolError,
        }
    }
}

/// An HTTP/3 configuration.
pub struct Config {
    num_placeholders: u64,
    max_header_list_size: u64,
    qpack_max_table_capacity: u64,
    qpack_blocked_streams: u64,
}

impl Config {
    pub fn new(
        num_placeholders: u64, max_header_list_size: u64,
        qpack_max_table_capacity: u64, qpack_blocked_streams: u64,
    ) -> Result<Config> {
        Ok(Config {
            num_placeholders,
            max_header_list_size,
            qpack_max_table_capacity,
            qpack_blocked_streams,
        })
    }
}

/// A name-value pair representing a raw HTTP header.
#[derive(Clone, Debug, PartialEq)]
pub struct Header(String, String);

impl Header {
    /// Creates a new header.
    pub fn new(name: &str, value: &str) -> Header {
        Header(String::from(name), String::from(value))
    }

    /// Returns the header's name.
    pub fn name(&self) -> &str {
        &self.0
    }

    /// Returns the header's value.
    pub fn value(&self) -> &str {
        &self.1
    }
}

/// An HTTP/3 connection event.
#[derive(Clone, Debug, PartialEq)]
pub enum Event {
    /// Request/response headers were received.
    Headers(Vec<Header>),

    /// Data was received.
    Data(Vec<u8>),
}

struct ConnectionSettings {
    pub num_placeholders: Option<u64>,
    pub max_header_list_size: Option<u64>,
    pub qpack_max_table_capacity: Option<u64>,
    pub qpack_blocked_streams: Option<u64>,
}

struct QpackStreams {
    pub encoder_stream_id: Option<u64>,
    pub decoder_stream_id: Option<u64>,
}

/// An HTTP/3 connection.
pub struct Connection {
    is_server: bool,

    highest_request_stream_id: u64,
    highest_uni_stream_id: u64,

    streams: BTreeMap<u64, stream::Stream>,

    local_settings: ConnectionSettings,
    peer_settings: ConnectionSettings,

    control_stream_id: Option<u64>,
    peer_control_stream_id: Option<u64>,

    qpack_encoder: qpack::Encoder,
    qpack_decoder: qpack::Decoder,

    local_qpack_streams: QpackStreams,
    peer_qpack_streams: QpackStreams,
}

impl Connection {
    fn new(config: &Config, is_server: bool) -> Result<Connection> {
        let initial_uni_stream_id = if is_server { 0x3 } else { 0x2 };

        Ok(Connection {
            is_server,

            highest_request_stream_id: 0,
            highest_uni_stream_id: initial_uni_stream_id,

            streams: BTreeMap::new(),

            local_settings: ConnectionSettings {
                num_placeholders: Some(config.num_placeholders),
                max_header_list_size: Some(config.max_header_list_size),
                qpack_max_table_capacity: Some(config.qpack_max_table_capacity),
                qpack_blocked_streams: Some(config.qpack_blocked_streams),
            },

            peer_settings: ConnectionSettings {
                num_placeholders: None,
                max_header_list_size: None,
                qpack_max_table_capacity: None,
                qpack_blocked_streams: None,
            },

            control_stream_id: None,
            peer_control_stream_id: None,

            qpack_encoder: qpack::Encoder::new(),
            qpack_decoder: qpack::Decoder::new(),

            local_qpack_streams: QpackStreams {
                encoder_stream_id: None,
                decoder_stream_id: None,
            },
            peer_qpack_streams: QpackStreams {
                encoder_stream_id: None,
                decoder_stream_id: None,
            },
        })
    }

    /// Creates a new HTTP/3 connection using the provided QUIC connection.
    ///
    /// This will also initiate the HTTP/3 handshake with the peer by opening
    /// all control streams (including QPACK) and sending the local settings.
    pub fn with_transport(
        conn: &mut super::Connection, config: &Config,
    ) -> Result<Connection> {
        let mut http3_conn = Connection::new(config, conn.is_server)?;

        http3_conn.send_settings(conn)?;
        http3_conn.open_qpack_streams(conn)?;

        if conn.grease {
            http3_conn.open_grease_stream(conn)?;
        }

        Ok(http3_conn)
    }

    /// Sends an HTTP/3 request.
    ///
    /// The request is encoded from the provided list of headers, and sent on
    /// a newly allocated stream.
    ///
    /// On success the newly allocated stream ID is returned.
    pub fn send_request(
        &mut self, conn: &mut super::Connection, headers: &[Header], fin: bool,
    ) -> Result<u64> {
        let stream_id = self.get_available_request_stream()?;
        self.streams
            .insert(stream_id, stream::Stream::new(stream_id, true));

        self.send_headers(conn, stream_id, headers, fin)?;

        Ok(stream_id)
    }

    /// Sends an HTTP/3 response on the specified stream.
    pub fn send_response(
        &mut self, conn: &mut super::Connection, stream_id: u64,
        headers: &[Header], fin: bool,
    ) -> Result<()> {
        self.send_headers(conn, stream_id, headers, fin)?;

        Ok(())
    }

    fn send_headers(
        &mut self, conn: &mut super::Connection, stream_id: u64,
        headers: &[Header], fin: bool,
    ) -> Result<()> {
        let mut d = [42; 10];

        let headers_len = headers
            .iter()
            .fold(0, |acc, h| acc + h.value().len() + h.name().len() + 32);
        let mut header_block = vec![0; headers_len];
        let len = self
            .qpack_encoder
            .encode(&headers, &mut header_block)
            .map_err(|_| Error::InternalError)?;
        header_block.truncate(len);

        let mut b = octets::Octets::with_slice(&mut d);
        b.put_varint(frame::HEADERS_FRAME_TYPE_ID)?;
        b.put_varint(len as u64)?;

        let off = b.off();

        if conn.grease {
            self.send_grease_frames(conn, stream_id)?;
        }

        trace!(
            "{} sending HEADERS of size {} on stream {}",
            conn.trace_id(),
            off + len,
            stream_id
        );

        conn.stream_send(stream_id, &d[..off], fin)?;

        conn.stream_send(stream_id, &header_block, fin)?;

        Ok(())
    }

    /// Sends an HTTP/3 body chunk on the given stream.
    ///
    /// On success the number of bytes written is returned.
    pub fn send_body(
        &mut self, conn: &mut super::Connection, stream_id: u64, body: &[u8],
        fin: bool,
    ) -> Result<usize> {
        let mut d = [42; 10];

        let mut b = octets::Octets::with_slice(&mut d);
        b.put_varint(frame::DATA_FRAME_TYPE_ID)?;
        b.put_varint(body.len() as u64)?;

        let off = b.off();

        trace!(
            "{} sending DATA frame of size {} on stream {}",
            conn.trace_id(),
            off + body.len(),
            stream_id
        );

        conn.stream_send(stream_id, &d[..off], false)?;

        // Return how many bytes were written, excluding the frame header.
        let written = conn.stream_send(stream_id, body, fin)?;

        Ok(written)
    }

    /// Processes HTTP/3 data received from the peer.
    ///
    /// On success it returns an [`Event`] as well as the event's source stream
    /// ID. The stream ID can be used when calling [`send_response()`] and
    /// [`send_body()`] when responding to incoming requests.
    ///
    /// [`Event`]: enum.Event.html
    /// [`send_response()`]: struct.Connection.html#method.send_response
    /// [`send_body()`]: struct.Connection.html#method.send_body
    pub fn poll(&mut self, conn: &mut super::Connection) -> Result<(u64, Event)> {
        let streams: Vec<u64> = conn.readable().collect();

        // Process HTTP/3 data from readable streams.
        for s in streams {
            trace!("{} stream id {} is readable", conn.trace_id(), s);

            loop {
                match self.handle_stream(conn, s) {
                    Ok(_) => break,

                    Err(Error::Done) => break,

                    Err(Error::BufferTooShort) => {
                        // Keep processing transport stream.
                    },

                    Err(e) => return Err(e),
                };
            }
        }

        for (stream_id, stream) in self.streams.iter_mut() {
            if let Some(frame) = stream.get_frame() {
                trace!(
                    "{} rx frm {:?} on stream {}",
                    conn.trace_id(),
                    frame,
                    stream_id
                );

                match frame {
                    frame::Frame::Settings {
                        num_placeholders,
                        max_header_list_size,
                        qpack_max_table_capacity,
                        qpack_blocked_streams,
                        ..
                    } => {
                        if self.is_server && num_placeholders.is_some() {
                            conn.close(
                                true,
                                Error::WrongSettingDirection.to_wire(),
                                b"Num placeholder setting received by server.",
                            )?;

                            return Err(Error::WrongSettingDirection);
                        }

                        self.peer_settings = ConnectionSettings {
                            num_placeholders,
                            max_header_list_size,
                            qpack_max_table_capacity,
                            qpack_blocked_streams,
                        };
                    },

                    frame::Frame::Headers { mut header_block } => {
                        if Some(*stream_id) == self.peer_control_stream_id {
                            Connection::close_unexpected_frame(
                                conn,
                                b"HEADERS received on control stream",
                            )?;
                        }

                        let headers = self
                            .qpack_decoder
                            .decode(&mut header_block[..])
                            .map_err(|_| Error::QpackDecompressionFailed)?;
                        return Ok((*stream_id, Event::Headers(headers)));
                    },

                    frame::Frame::Data { payload } => {
                        if Some(*stream_id) == self.peer_control_stream_id {
                            Connection::close_unexpected_frame(
                                conn,
                                b"DATA received on control stream",
                            )?;
                        }

                        return Ok((*stream_id, Event::Data(payload)));
                    },

                    frame::Frame::GoAway { .. } => {
                        if Some(*stream_id) != self.peer_control_stream_id {
                            Connection::close_unexpected_frame(
                                conn,
                                b"GOAWAY received on non-control stream",
                            )?;
                        }

                        if self.is_server {
                            Connection::close_unexpected_frame(
                                conn,
                                b"GOWAY received on server",
                            )?;
                        }

                        // TODO: implement GOAWAY
                    },

                    frame::Frame::MaxPushId { .. } => {
                        if Some(*stream_id) != self.peer_control_stream_id {
                            Connection::close_unexpected_frame(
                                conn,
                                b"MAX_PUSH_ID received on non-control stream",
                            )?;
                        }

                        if !self.is_server {
                            Connection::close_unexpected_frame(
                                conn,
                                b"MAX_PUSH_ID received by client",
                            )?;
                        }

                        // TODO: implement MAX_PUSH_ID
                    },

                    frame::Frame::PushPromise { .. } => {
                        if stream_id % 4 != 0 {
                            Connection::close_unexpected_frame(
                                conn,
                                b"PUSH_PROMISE received on non-request stream",
                            )?;
                        }

                        // TODO: implement PUSH_PROMISE
                    },

                    frame::Frame::DuplicatePush { .. } => {
                        if stream_id % 4 != 0 {
                            Connection::close_unexpected_frame(
                                conn,
                                b"DUPLICATE_PUSH received on non-request stream",
                            )?;
                        }

                        // TODO: implement DUPLICATE_PUSH
                    },

                    frame::Frame::CancelPush { .. } => {
                        if Some(*stream_id) != self.peer_control_stream_id {
                            Connection::close_unexpected_frame(
                                conn,
                                b"CANCEL_PUSH received on non-control stream",
                            )?;
                        }

                        // TODO: implement CANCEL_PUSH frame
                    },
                }
            }
        }

        Err(Error::Done)
    }

    fn close_unexpected_frame(
        conn: &mut super::Connection, reason: &[u8],
    ) -> Result<()> {
        conn.close(true, Error::UnexpectedFrame.to_wire(), reason)?;

        Err(Error::UnexpectedFrame)
    }

    fn close_wrong_stream_count(
        conn: &mut super::Connection, reason: &[u8],
    ) -> Result<()> {
        conn.close(true, Error::WrongStreamCount.to_wire(), reason)?;

        Err(Error::WrongStreamCount)
    }

    /// Allocates a new request stream ID for the local endpoint to use.
    fn get_available_request_stream(&mut self) -> Result<u64> {
        if self.highest_request_stream_id < std::u64::MAX {
            let ret = self.highest_request_stream_id;
            self.highest_request_stream_id += 4;
            return Ok(ret);
        }

        Err(Error::LimitExceeded)
    }

    /// Allocates a new unidirectional stream ID for the local endpoint to use.
    fn get_available_uni_stream(&mut self) -> Result<u64> {
        if self.highest_uni_stream_id < std::u64::MAX {
            let ret = self.highest_uni_stream_id;
            self.highest_uni_stream_id += 4;
            return Ok(ret);
        }

        Err(Error::LimitExceeded)
    }

    /// Opens HTTP/3 control stream, if not already opened.
    fn open_control_stream(
        &mut self, conn: &mut super::Connection,
    ) -> Result<()> {
        if self.control_stream_id.is_none() {
            let stream_id = self.get_available_uni_stream()?;

            let mut d = [42; 8];
            let mut b = octets::Octets::with_slice(&mut d);
            b.put_varint(stream::HTTP3_CONTROL_STREAM_TYPE_ID)?;
            let off = b.off();

            conn.stream_send(stream_id, &d[..off], false)?;

            self.control_stream_id = Some(stream_id);
        }

        Ok(())
    }

    /// Opens QPACK encoder and decoder streams, if not already opened.
    fn open_qpack_streams(&mut self, conn: &mut super::Connection) -> Result<()> {
        if self.local_qpack_streams.encoder_stream_id.is_none() {
            let stream_id = self.get_available_uni_stream()?;

            let mut d = [0; 8];
            let mut b = octets::Octets::with_slice(&mut d);
            b.put_varint(stream::QPACK_ENCODER_STREAM_TYPE_ID)?;
            let off = b.off();

            conn.stream_send(stream_id, &d[..off], false)?;

            self.local_qpack_streams.encoder_stream_id = Some(stream_id);
        }

        if self.local_qpack_streams.decoder_stream_id.is_none() {
            let stream_id = self.get_available_uni_stream()?;

            let mut d = [0; 8];
            let mut b = octets::Octets::with_slice(&mut d);
            b.put_varint(stream::QPACK_DECODER_STREAM_TYPE_ID)?;
            let off = b.off();

            conn.stream_send(stream_id, &d[..off], false)?;

            self.local_qpack_streams.decoder_stream_id = Some(stream_id);
        }

        Ok(())
    }

    /// Generate am HTTP/3 GREASE variable length integer.
    fn grease_value() -> u64 {
        let n = std::cmp::min(super::rand::rand_u64(), 148_764_065_110_560_899);
        31 * n + 33
    }

    /// Send GREASE frames on the provided stream ID.
    fn send_grease_frames(
        &mut self, conn: &mut super::Connection, stream_id: u64,
    ) -> Result<()> {
        let mut d = [42; 128];

        let mut b = octets::Octets::with_slice(&mut d);

        // Empty GREASE frame.
        b.put_varint(Connection::grease_value())?;
        b.put_varint(0)?;

        // GREASE frame with payload.
        b.put_varint(Connection::grease_value())?;
        b.put_varint(18)?;

        trace!(
            "{} sending GREASE frames on stream id {}",
            conn.trace_id(),
            stream_id
        );

        let off = b.off();
        conn.stream_send(stream_id, &d[..off], false)?;

        conn.stream_send(stream_id, b"GREASE is the word", false)?;

        Ok(())
    }

    /// Opens a new unidirectional stream with a GREASE type and sends some
    /// unframed payload.
    fn open_grease_stream(&mut self, conn: &mut super::Connection) -> Result<()> {
        let stream_id = self.get_available_uni_stream()?;

        let mut d = [0; 8];
        let mut b = octets::Octets::with_slice(&mut d);
        b.put_varint(Connection::grease_value())?;

        let off = b.off();

        match conn.stream_send(stream_id, &d[..off], false) {
            Ok(_v) => {
                trace!(
                    "{} sending GREASE stream on stream id {}",
                    conn.trace_id(),
                    stream_id
                );
                conn.stream_send(stream_id, b"GREASE is the word", false)?;
            },
            Err(super::Error::StreamLimit) => {
                trace!(
                    "{} sending GREASE stream was blocked on stream id {}",
                    conn.trace_id(),
                    stream_id
                );

                return Ok(());
            },
            Err(e) => {
                return Err(Error::from(e));
            },
        };

        Ok(())
    }

    /// Sends SETTINGS frame based on HTTP/3 configuration.
    fn send_settings(&mut self, conn: &mut super::Connection) -> Result<()> {
        let mut d = [42; 128];

        self.open_control_stream(conn)?;

        // Client cannot send placeholders, so validate here
        let num_placeholders = if self.is_server {
            self.local_settings.num_placeholders
        } else {
            None
        };

        let grease = if conn.grease {
            Some((Connection::grease_value(), Connection::grease_value()))
        } else {
            None
        };

        let frame = frame::Frame::Settings {
            num_placeholders,
            max_header_list_size: self.local_settings.max_header_list_size,
            qpack_max_table_capacity: self
                .local_settings
                .qpack_max_table_capacity,
            qpack_blocked_streams: self.local_settings.qpack_blocked_streams,
            grease,
        };

        let mut b = octets::Octets::with_slice(&mut d);

        frame.to_bytes(&mut b)?;

        let off = b.off();

        if let Some(id) = self.control_stream_id {
            conn.stream_send(id, &d[..off], false)?;
        }

        Ok(())
    }

    fn handle_stream(
        &mut self, conn: &mut super::Connection, stream_id: u64,
    ) -> Result<()> {
        let mut d = [0; 32768];

        let stream = self
            .streams
            .entry(stream_id)
            .or_insert_with(|| stream::Stream::new(stream_id, false));

        let (read, _fin) = conn.stream_recv(stream_id, &mut d)?;
        stream.push(&d[..read])?;

        trace!(
            "{} read {} bytes on stream {}",
            conn.trace_id(),
            read,
            stream_id
        );

        while stream.more() {
            match stream.state() {
                stream::State::StreamTypeLen => {
                    let varint_byte = stream.buf_bytes(1)?[0];
                    stream.set_next_varint_len(octets::varint_parse_len(
                        varint_byte,
                    ))?;
                },

                stream::State::StreamType => {
                    let varint = stream.get_varint()?;

                    let ty = stream::Type::deserialize(varint)?;

                    stream.set_stream_type(ty)?;

                    match &ty {
                        stream::Type::Control => {
                            // Only one control stream allowed.
                            if self.peer_control_stream_id.is_some() {
                                Connection::close_wrong_stream_count(
                                    conn,
                                    b"Received multiple control streams",
                                )?;
                            }

                            trace!(
                                "{} peer's control stream: {}",
                                conn.trace_id(),
                                stream_id
                            );

                            self.peer_control_stream_id = Some(stream_id);
                        },

                        stream::Type::Push => {
                            // Only clients can receive push stream.
                            if self.is_server {
                                conn.close(
                                    true,
                                    Error::WrongStreamDirection.to_wire(),
                                    b"Server received push stream.",
                                )?;

                                return Err(Error::WrongStreamDirection);
                            }
                        },

                        stream::Type::QpackEncoder => {
                            // Only one qpack encoder stream allowed.
                            if self.peer_qpack_streams.encoder_stream_id.is_some()
                            {
                                Connection::close_wrong_stream_count(
                                    conn,
                                    b"Received multiple QPACK encoder streams",
                                )?;
                            }

                            self.peer_qpack_streams.encoder_stream_id =
                                Some(stream_id);
                        },

                        stream::Type::QpackDecoder => {
                            // Only one qpack decoder allowed.
                            if self.peer_qpack_streams.decoder_stream_id.is_some()
                            {
                                Connection::close_wrong_stream_count(
                                    conn,
                                    b"Received multiple QPACK decoder streams",
                                )?;
                            }

                            self.peer_qpack_streams.decoder_stream_id =
                                Some(stream_id);
                        },

                        stream::Type::Unknown => {
                            // Unknown stream types are ignored.
                            // TODO: we MAY send STOP_SENDING
                        },

                        stream::Type::Request => unreachable!(),
                    }
                },

                stream::State::FramePayloadLenLen => {
                    let varint_byte = stream.buf_bytes(1)?[0];
                    stream.set_next_varint_len(octets::varint_parse_len(
                        varint_byte,
                    ))?
                },

                stream::State::FramePayloadLen => {
                    let varint = stream.get_varint()?;
                    stream.set_frame_payload_len(varint)?;
                },

                stream::State::FrameTypeLen => {
                    let varint_byte = stream.buf_bytes(1)?[0];
                    stream.set_next_varint_len(octets::varint_parse_len(
                        varint_byte,
                    ))?
                },

                stream::State::FrameType => {
                    let varint = stream.get_varint()?;
                    stream.set_frame_type(varint)?;
                },

                stream::State::FramePayload => {
                    stream.parse_frame()?;
                },

                stream::State::QpackInstruction => {
                    return Err(Error::Done);
                },

                stream::State::Done => {
                    return Err(Error::Done);
                },

                _ => (),
            }
        }

        Err(Error::Done)
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    use crate::testing;

    #[test]
    fn grease_value_in_varint_limit() {
        assert!(Connection::grease_value() < 2u64.pow(62) - 1);
    }

    #[test]
    fn simple_request() {
        let mut buf = [0; 65535];

        let mut config = crate::Config::new(crate::VERSION_DRAFT19).unwrap();
        config
            .load_cert_chain_from_pem_file("examples/cert.crt")
            .unwrap();
        config
            .load_priv_key_from_pem_file("examples/cert.key")
            .unwrap();
        config.set_application_protos(b"\x02h3").unwrap();
        config.set_initial_max_data(150);
        config.set_initial_max_stream_data_bidi_local(150);
        config.set_initial_max_stream_data_bidi_remote(150);
        config.set_initial_max_stream_data_uni(150);
        config.set_initial_max_streams_bidi(3);
        config.set_initial_max_streams_uni(3);
        config.verify_peer(false);

        let mut pipe = testing::Pipe::with_config(&mut config).unwrap();

        assert_eq!(pipe.handshake(&mut buf), Ok(()));

        let config = Config::new(0, 1024, 0, 0).unwrap();

        let mut h3_cln =
            Connection::with_transport(&mut pipe.client, &config).unwrap();
        let mut h3_srv =
            Connection::with_transport(&mut pipe.server, &config).unwrap();

        pipe.advance(&mut buf).ok();

        let req = [
            Header::new(":method", "GET"),
            Header::new(":scheme", "https"),
            Header::new(":authority", "quic.tech"),
            Header::new(":path", "/test"),
            Header::new("user-agent", "quiche-test"),
        ];

        let stream = h3_cln.send_request(&mut pipe.client, &req, true).unwrap();
        assert_eq!(stream, 0);

        pipe.advance(&mut buf).ok();

        let ev = h3_srv.poll(&mut pipe.server).unwrap();
        assert_eq!(ev, (stream, Event::Headers(req.to_vec())));

        let resp = [
            Header::new(":status", "200"),
            Header::new("server", "quiche-test"),
        ];

        h3_srv
            .send_response(&mut pipe.server, stream, &resp, true)
            .unwrap();

        pipe.advance(&mut buf).ok();

        let ev = h3_cln.poll(&mut pipe.client).unwrap();
        assert_eq!(ev, (stream, Event::Headers(resp.to_vec())));
    }

}

mod ffi;
mod frame;
#[doc(hidden)]
pub mod qpack;
mod stream;
