// 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 header compression (QPACK).

const INDEXED: u8 = 0b1000_0000;
const INDEXED_WITH_POST_BASE: u8 = 0b0001_0000;
const LITERAL: u8 = 0b0010_0000;
const LITERAL_WITH_NAME_REF: u8 = 0b0100_0000;

/// A specialized [`Result`] type for quiche QPACK operations.
///
/// This type is used throughout quiche's QPACK 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>;

/// A QPACK error.
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Error {
    /// The provided buffer is too short.
    BufferTooShort,

    /// The QPACK header block's huffman encoding is invalid.
    InvalidHuffmanEncoding,

    /// The QPACK static table index provided doesn't exist.
    InvalidStaticTableIndex,

    /// The decoded QPACK header name or value is not valid.
    InvalidHeaderValue,

    /// The decoded header list exceeded the size limit.
    HeaderListTooLarge,
}

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 source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        None
    }
}

impl std::convert::From<crate::octets::BufferTooShortError> for Error {
    fn from(_err: crate::octets::BufferTooShortError) -> Self {
        Error::BufferTooShort
    }
}

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

    use super::*;

    #[test]
    fn encode_decode() {
        let mut encoded = [0u8; 240];

        let headers = vec![
            h3::Header::new(":path", "/rsrc.php/v3/yn/r/rIPZ9Qkrdd9.png"),
            h3::Header::new("accept-encoding", "gzip, deflate, br"),
            h3::Header::new("accept-language", "en-US,en;q=0.9"),
            h3::Header::new("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.70 Safari/537.36"),
            h3::Header::new("accept", "image/webp,image/apng,image/*,*/*;q=0.8"),
            h3::Header::new("referer", "https://static.xx.fbcdn.net/rsrc.php/v3/yT/l/0,cross/dzXGESIlGQQ.css"),
            h3::Header::new(":authority", "static.xx.fbcdn.net"),
            h3::Header::new(":scheme", "https"),
            h3::Header::new(":method", "GET"),
        ];

        let mut enc = Encoder::new();
        assert_eq!(enc.encode(&headers, &mut encoded), Ok(240));

        let mut dec = Decoder::new();
        assert_eq!(dec.decode(&mut encoded, std::u64::MAX), Ok(headers));
    }

    #[test]
    fn lower_case() {
        let mut encoded = [0u8; 35];

        let headers_expected = vec![
            crate::h3::Header::new(":status", "200"),
            crate::h3::Header::new(":path", "/HeLlO"),
            crate::h3::Header::new("woot", "woot"),
            crate::h3::Header::new("hello", "WorlD"),
            crate::h3::Header::new("foo", "BaR"),
        ];

        // Header.
        let headers_in = vec![
            crate::h3::Header::new(":StAtUs", "200"),
            crate::h3::Header::new(":PaTh", "/HeLlO"),
            crate::h3::Header::new("WooT", "woot"),
            crate::h3::Header::new("hello", "WorlD"),
            crate::h3::Header::new("fOo", "BaR"),
        ];

        let mut enc = Encoder::new();
        assert_eq!(enc.encode(&headers_in, &mut encoded), Ok(35));

        let mut dec = Decoder::new();
        let headers_out = dec.decode(&mut encoded, std::u64::MAX).unwrap();

        assert_eq!(headers_expected, headers_out);

        // HeaderRef.
        let headers_in = vec![
            crate::h3::HeaderRef::new(":StAtUs", "200"),
            crate::h3::HeaderRef::new(":PaTh", "/HeLlO"),
            crate::h3::HeaderRef::new("WooT", "woot"),
            crate::h3::HeaderRef::new("hello", "WorlD"),
            crate::h3::HeaderRef::new("fOo", "BaR"),
        ];

        let mut enc = Encoder::new();
        assert_eq!(enc.encode(&headers_in, &mut encoded), Ok(35));

        let mut dec = Decoder::new();
        let headers_out = dec.decode(&mut encoded, std::u64::MAX).unwrap();

        assert_eq!(headers_expected, headers_out);
    }
}

pub use decoder::Decoder;
pub use encoder::Encoder;

mod decoder;
mod encoder;
mod huffman;
mod static_table;
