use crate::error::*;
use crate::header::*;
use crate::{BerParser, DerParser, FromBer, Length, Tag};
use nom::bytes::streaming::take;
use nom::{Err, Needed, Offset};
use rusticata_macros::custom_check;

/// Default maximum recursion limit
pub const MAX_RECURSION: usize = 50;

/// Default maximum object size (2^32)
// pub const MAX_OBJECT_SIZE: usize = 4_294_967_295;

pub trait GetObjectContent {
    /// Return the raw content (bytes) of the next ASN.1 encoded object
    ///
    /// Note: if using BER and length is indefinite, terminating End-Of-Content is NOT included
    fn get_object_content<'a>(
        i: &'a [u8],
        hdr: &'_ Header,
        max_depth: usize,
    ) -> ParseResult<'a, &'a [u8]>;
}

impl GetObjectContent for BerParser {
    fn get_object_content<'a>(
        i: &'a [u8],
        hdr: &'_ Header,
        max_depth: usize,
    ) -> ParseResult<'a, &'a [u8]> {
        let start_i = i;
        let (i, _) = ber_skip_object_content(i, hdr, max_depth)?;
        let len = start_i.offset(i);
        let (content, i) = start_i.split_at(len);
        // if len is indefinite, there are 2 extra bytes for EOC
        if hdr.length == Length::Indefinite {
            let len = content.len();
            assert!(len >= 2);
            Ok((i, &content[..len - 2]))
        } else {
            Ok((i, content))
        }
    }
}

impl GetObjectContent for DerParser {
    /// Skip object content, accepting only DER
    ///
    /// This this function is for DER only, it cannot go into recursion (no indefinite length)
    fn get_object_content<'a>(
        i: &'a [u8],
        hdr: &'_ Header,
        _max_depth: usize,
    ) -> ParseResult<'a, &'a [u8]> {
        match hdr.length {
            Length::Definite(l) => take(l)(i),
            Length::Indefinite => Err(Err::Error(Error::DerConstraintFailed(
                DerConstraint::IndefiniteLength,
            ))),
        }
    }
}

/// Skip object content, and return true if object was End-Of-Content
fn ber_skip_object_content<'a>(
    i: &'a [u8],
    hdr: &Header,
    max_depth: usize,
) -> ParseResult<'a, bool> {
    if max_depth == 0 {
        return Err(Err::Error(Error::BerMaxDepth));
    }
    match hdr.length {
        Length::Definite(l) => {
            if l == 0 && hdr.tag == Tag::EndOfContent {
                return Ok((i, true));
            }
            let (i, _) = take(l)(i)?;
            Ok((i, false))
        }
        Length::Indefinite => {
            hdr.assert_constructed()?;
            // read objects until EndOfContent (00 00)
            // this is recursive
            let mut i = i;
            loop {
                let (i2, header2) = Header::from_ber(i)?;
                let (i3, eoc) = ber_skip_object_content(i2, &header2, max_depth - 1)?;
                if eoc {
                    // return false, since top object was not EndOfContent
                    return Ok((i3, false));
                }
                i = i3;
            }
        }
    }
}

/// Try to parse input bytes as u64
#[inline]
pub(crate) fn bytes_to_u64(s: &[u8]) -> core::result::Result<u64, Error> {
    let mut u: u64 = 0;
    for &c in s {
        if u & 0xff00_0000_0000_0000 != 0 {
            return Err(Error::IntegerTooLarge);
        }
        u <<= 8;
        u |= u64::from(c);
    }
    Ok(u)
}

pub(crate) fn parse_identifier(i: &[u8]) -> ParseResult<(u8, u8, u32, &[u8])> {
    if i.is_empty() {
        Err(Err::Incomplete(Needed::new(1)))
    } else {
        let a = i[0] >> 6;
        let b = u8::from(i[0] & 0b0010_0000 != 0);
        let mut c = u32::from(i[0] & 0b0001_1111);

        let mut tag_byte_count = 1;

        if c == 0x1f {
            c = 0;
            loop {
                // Make sure we don't read past the end of our data.
                custom_check!(i, tag_byte_count >= i.len(), Error::InvalidTag)?;

                // With tag defined as u32 the most we can fit in is four tag bytes.
                // (X.690 doesn't actually specify maximum tag width.)
                custom_check!(i, tag_byte_count > 5, Error::InvalidTag)?;

                c = (c << 7) | (u32::from(i[tag_byte_count]) & 0x7f);
                let done = i[tag_byte_count] & 0x80 == 0;
                tag_byte_count += 1;
                if done {
                    break;
                }
            }
        }

        let (raw_tag, rem) = i.split_at(tag_byte_count);

        Ok((rem, (a, b, c, raw_tag)))
    }
}

/// Return the MSB and the rest of the first byte, or an error
pub(crate) fn parse_ber_length_byte(i: &[u8]) -> ParseResult<(u8, u8)> {
    if i.is_empty() {
        Err(Err::Incomplete(Needed::new(1)))
    } else {
        let a = i[0] >> 7;
        let b = i[0] & 0b0111_1111;
        Ok((&i[1..], (a, b)))
    }
}

#[doc(hidden)]
#[macro_export]
macro_rules! der_constraint_fail_if(
    ($slice:expr, $cond:expr, $constraint:expr) => (
        {
            if $cond {
                return Err(::nom::Err::Error(Error::DerConstraintFailed($constraint)));
            }
        }
    );
);
