// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::internal_utils::*;
use crate::parser::mp4box::BoxSize;

#[derive(Debug)]
pub struct IBitStream<'a> {
    pub data: &'a [u8],
    pub bit_offset: usize,
}

impl IBitStream<'_> {
    fn read_bit(&mut self) -> AvifResult<u8> {
        let byte_offset = self.bit_offset / 8;
        if byte_offset >= self.data.len() {
            return Err(AvifError::BmffParseFailed("Not enough bits".into()));
        }
        let byte = self.data[byte_offset];
        let shift = 7 - (self.bit_offset % 8);
        self.bit_offset += 1;
        Ok((byte >> shift) & 0x01)
    }

    pub(crate) fn read(&mut self, n: usize) -> AvifResult<u32> {
        assert!(n <= 32);
        let mut value: u32 = 0;
        for _i in 0..n {
            value <<= 1;
            value |= self.read_bit()? as u32;
        }
        Ok(value)
    }

    pub(crate) fn read_bool(&mut self) -> AvifResult<bool> {
        let bit = self.read_bit()?;
        Ok(bit == 1)
    }

    pub(crate) fn skip(&mut self, n: usize) -> AvifResult<()> {
        if checked_add!(self.bit_offset, n)? > checked_mul!(self.data.len(), 8)? {
            return Err(AvifError::BmffParseFailed("Not enough bytes".into()));
        }
        self.bit_offset += n;
        Ok(())
    }

    pub(crate) fn skip_uvlc(&mut self) -> AvifResult<()> {
        // See the section 4.10.3. uvlc() of the AV1 specification.
        let mut leading_zeros = 0u128; // leadingZeros
        while !self.read_bool()? {
            leading_zeros += 1;
        }
        if leading_zeros < 32 {
            self.skip(leading_zeros as usize)?; // f(leadingZeros) value;
        }
        Ok(())
    }

    pub(crate) fn remaining_bits(&self) -> AvifResult<usize> {
        checked_sub!(checked_mul!(self.data.len(), 8)?, self.bit_offset)
    }
}

#[derive(Debug)]
pub struct IStream<'a> {
    pub data: &'a [u8],
    pub offset: usize,
}

impl IStream<'_> {
    pub(crate) fn create(data: &[u8]) -> IStream {
        IStream { data, offset: 0 }
    }

    fn check(&self, size: usize) -> AvifResult<()> {
        if self.bytes_left()? < size {
            return Err(AvifError::BmffParseFailed("".into()));
        }
        Ok(())
    }

    pub(crate) fn sub_stream(&mut self, size: &BoxSize) -> AvifResult<IStream> {
        let offset = self.offset;
        checked_incr!(
            self.offset,
            match size {
                BoxSize::FixedSize(size) => {
                    self.check(*size)?;
                    *size
                }
                BoxSize::UntilEndOfStream => self.bytes_left()?,
            }
        );
        Ok(IStream {
            data: &self.data[offset..self.offset],
            offset: 0,
        })
    }

    pub(crate) fn sub_bit_stream(&mut self, size: usize) -> AvifResult<IBitStream> {
        self.check(size)?;
        let offset = self.offset;
        checked_incr!(self.offset, size);
        Ok(IBitStream {
            data: &self.data[offset..self.offset],
            bit_offset: 0,
        })
    }

    pub(crate) fn bytes_left(&self) -> AvifResult<usize> {
        if self.data.len() < self.offset {
            return Err(AvifError::UnknownError("".into()));
        }
        Ok(self.data.len() - self.offset)
    }

    pub(crate) fn has_bytes_left(&self) -> AvifResult<bool> {
        Ok(self.bytes_left()? > 0)
    }

    pub(crate) fn get_slice(&mut self, size: usize) -> AvifResult<&[u8]> {
        self.check(size)?;
        let offset_start = self.offset;
        checked_incr!(self.offset, size);
        Ok(&self.data[offset_start..offset_start + size])
    }

    pub(crate) fn get_immutable_vec(&self, size: usize) -> AvifResult<Vec<u8>> {
        self.check(size)?;
        Ok(self.data[self.offset..self.offset + size].to_vec())
    }

    fn get_vec(&mut self, size: usize) -> AvifResult<Vec<u8>> {
        Ok(self.get_slice(size)?.to_vec())
    }

    pub(crate) fn read_u8(&mut self) -> AvifResult<u8> {
        self.check(1)?;
        let value = self.data[self.offset];
        checked_incr!(self.offset, 1);
        Ok(value)
    }

    pub(crate) fn read_u16(&mut self) -> AvifResult<u16> {
        Ok(u16::from_be_bytes(self.get_slice(2)?.try_into().unwrap()))
    }

    pub(crate) fn read_u24(&mut self) -> AvifResult<u32> {
        Ok(self.read_uxx(3)? as u32)
    }

    pub(crate) fn read_u32(&mut self) -> AvifResult<u32> {
        Ok(u32::from_be_bytes(self.get_slice(4)?.try_into().unwrap()))
    }

    pub(crate) fn read_u64(&mut self) -> AvifResult<u64> {
        Ok(u64::from_be_bytes(self.get_slice(8)?.try_into().unwrap()))
    }

    pub(crate) fn read_i32(&mut self) -> AvifResult<i32> {
        Ok(self.read_u32()? as i32)
    }

    pub(crate) fn read_i16(&mut self) -> AvifResult<i16> {
        Ok(self.read_u16()? as i16)
    }

    pub(crate) fn skip_u32(&mut self) -> AvifResult<()> {
        self.skip(4)
    }

    pub(crate) fn skip_u64(&mut self) -> AvifResult<()> {
        self.skip(8)
    }

    pub(crate) fn read_fraction(&mut self) -> AvifResult<Fraction> {
        Ok(Fraction(self.read_i32()?, self.read_u32()?))
    }

    pub(crate) fn read_ufraction(&mut self) -> AvifResult<UFraction> {
        Ok(UFraction(self.read_u32()?, self.read_u32()?))
    }

    // Reads size characters of a non-null-terminated string.
    pub(crate) fn read_string(&mut self, size: usize) -> AvifResult<String> {
        Ok(String::from_utf8(self.get_vec(size)?).unwrap_or("".into()))
    }

    // Reads an xx-byte unsigner integer.
    pub(crate) fn read_uxx(&mut self, xx: u8) -> AvifResult<u64> {
        let n: usize = xx.into();
        if n == 0 {
            return Ok(0);
        }
        if n > 8 {
            return Err(AvifError::NotImplemented);
        }
        let mut out = [0; 8];
        let start = out.len() - n;
        out[start..].copy_from_slice(self.get_slice(n)?);
        Ok(u64::from_be_bytes(out))
    }

    // Reads a null-terminated string.
    pub(crate) fn read_c_string(&mut self) -> AvifResult<String> {
        self.check(1)?;
        let null_position = self.data[self.offset..]
            .iter()
            .position(|&x| x == b'\0')
            .ok_or(AvifError::BmffParseFailed("".into()))?;
        let range = self.offset..self.offset + null_position;
        self.offset += null_position + 1;
        Ok(String::from_utf8(self.data[range].to_vec()).unwrap_or("".into()))
    }

    pub(crate) fn read_version_and_flags(&mut self) -> AvifResult<(u8, u32)> {
        let version = self.read_u8()?;
        let flags = self.read_u24()?;
        Ok((version, flags))
    }

    pub(crate) fn read_and_enforce_version_and_flags(
        &mut self,
        enforced_version: u8,
    ) -> AvifResult<(u8, u32)> {
        let (version, flags) = self.read_version_and_flags()?;
        if version != enforced_version {
            return Err(AvifError::BmffParseFailed("".into()));
        }
        Ok((version, flags))
    }

    pub(crate) fn skip(&mut self, size: usize) -> AvifResult<()> {
        self.check(size)?;
        checked_incr!(self.offset, size);
        Ok(())
    }

    pub(crate) fn rewind(&mut self, size: usize) -> AvifResult<()> {
        checked_decr!(self.offset, size);
        Ok(())
    }

    pub(crate) fn read_uleb128(&mut self) -> AvifResult<u32> {
        // See the section 4.10.5. of the AV1 specification.
        let mut value: u64 = 0;
        for i in 0..8 {
            // leb128_byte contains 8 bits read from the bitstream.
            let leb128_byte = self.read_u8()?;
            // The bottom 7 bits are used to compute the variable value.
            value |= u64::from(leb128_byte & 0x7F) << (i * 7);
            // The most significant bit is used to indicate that there are more
            // bytes to be read.
            if (leb128_byte & 0x80) == 0 {
                // It is a requirement of bitstream conformance that the value
                // returned from the leb128 parsing process is less than or
                // equal to (1 << 32)-1.
                return u32_from_u64(value);
            }
        }
        // It is a requirement of bitstream conformance that the most
        // significant bit of leb128_byte is equal to 0 if i is equal to 7.
        Err(AvifError::BmffParseFailed(
            "uleb value did not terminate after 8 bytes".into(),
        ))
    }
}

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

    #[test]
    fn read_uxx() {
        let mut stream = IStream::create(&[1, 2, 3, 4, 5, 6, 7, 8]);
        assert_eq!(stream.read_uxx(0), Ok(0));
        assert_eq!(stream.offset, 0);
        assert_eq!(stream.read_uxx(1), Ok(1));
        assert_eq!(stream.offset, 1);
        stream.offset = 0;
        assert_eq!(stream.read_uxx(2), Ok(258));
        stream.offset = 0;
        assert_eq!(stream.read_u16(), Ok(258));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(3), Ok(66051));
        stream.offset = 0;
        assert_eq!(stream.read_u24(), Ok(66051));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(4), Ok(16909060));
        stream.offset = 0;
        assert_eq!(stream.read_u32(), Ok(16909060));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(5), Ok(4328719365));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(6), Ok(1108152157446));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(7), Ok(283686952306183));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(8), Ok(72623859790382856));
        stream.offset = 0;
        assert_eq!(stream.read_u64(), Ok(72623859790382856));
        stream.offset = 0;
        assert_eq!(stream.read_uxx(9), Err(AvifError::NotImplemented));
    }

    #[test]
    fn read_string() {
        let bytes = "abcd\0e".as_bytes();
        assert_eq!(IStream::create(bytes).read_string(4), Ok("abcd".into()));
        assert_eq!(IStream::create(bytes).read_string(5), Ok("abcd\0".into()));
        assert_eq!(IStream::create(bytes).read_string(6), Ok("abcd\0e".into()));
        assert!(matches!(
            IStream::create(bytes).read_string(8),
            Err(AvifError::BmffParseFailed(_))
        ));
        assert_eq!(IStream::create(bytes).read_c_string(), Ok("abcd".into()));
    }
}
