// 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::image::YuvRange;
use crate::internal_utils::stream::*;
use crate::internal_utils::*;
use crate::parser::mp4box::Av1CodecConfiguration;
use crate::*;

#[derive(Debug)]
struct ObuHeader {
    obu_type: u8,
    size: u32,
}

#[derive(Debug, Default)]
pub struct Av1SequenceHeader {
    reduced_still_picture_header: bool,
    max_width: u32,
    max_height: u32,
    bit_depth: u8,
    yuv_format: PixelFormat,
    #[allow(unused)]
    chroma_sample_position: ChromaSamplePosition,
    pub color_primaries: ColorPrimaries,
    pub transfer_characteristics: TransferCharacteristics,
    pub matrix_coefficients: MatrixCoefficients,
    pub yuv_range: YuvRange,
    config: Av1CodecConfiguration,
}

impl Av1SequenceHeader {
    fn parse_profile(&mut self, bits: &mut IBitStream) -> AvifResult<()> {
        self.config.seq_profile = bits.read(3)? as u8;
        if self.config.seq_profile > 2 {
            return Err(AvifError::BmffParseFailed("invalid seq_profile".into()));
        }
        let still_picture = bits.read_bool()?;
        self.reduced_still_picture_header = bits.read_bool()?;
        if self.reduced_still_picture_header && !still_picture {
            return Err(AvifError::BmffParseFailed(
                "invalid reduced_still_picture_header".into(),
            ));
        }
        if self.reduced_still_picture_header {
            self.config.seq_level_idx0 = bits.read(5)? as u8;
        } else {
            let mut buffer_delay_length = 0;
            let mut decoder_model_info_present_flag = false;
            let timing_info_present_flag = bits.read_bool()?;
            if timing_info_present_flag {
                // num_units_in_display_tick
                bits.skip(32)?;
                // time_scale
                bits.skip(32)?;
                let equal_picture_interval = bits.read_bool()?;
                if equal_picture_interval {
                    // num_ticks_per_picture_minus_1
                    bits.skip_uvlc()?;
                }
                decoder_model_info_present_flag = bits.read_bool()?;
                if decoder_model_info_present_flag {
                    let buffer_delay_length_minus_1 = bits.read(5)?;
                    buffer_delay_length = buffer_delay_length_minus_1 + 1;
                    // num_units_in_decoding_tick
                    bits.skip(32)?;
                    // buffer_removal_time_length_minus_1
                    bits.skip(5)?;
                    // frame_presentation_time_length_minus_1
                    bits.skip(5)?;
                }
            }
            let initial_display_delay_present_flag = bits.read_bool()?;
            let operating_points_cnt_minus_1 = bits.read(5)?;
            let operating_points_cnt = operating_points_cnt_minus_1 + 1;
            for i in 0..operating_points_cnt {
                // operating_point_idc
                bits.skip(12)?;
                let seq_level_idx = bits.read(5)?;
                if i == 0 {
                    self.config.seq_level_idx0 = seq_level_idx as u8;
                }
                if seq_level_idx > 7 {
                    let seq_tier = bits.read(1)?;
                    if i == 0 {
                        self.config.seq_tier0 = seq_tier as u8;
                    }
                }
                if decoder_model_info_present_flag {
                    let decoder_model_present_for_this_op = bits.read_bool()?;
                    if decoder_model_present_for_this_op {
                        // decoder_buffer_delay
                        bits.skip(buffer_delay_length as usize)?;
                        // encoder_buffer_delay
                        bits.skip(buffer_delay_length as usize)?;
                        // low_delay_mode_flag
                        bits.skip(1)?;
                    }
                }
                if initial_display_delay_present_flag {
                    let initial_display_delay_present_for_this_op = bits.read_bool()?;
                    if initial_display_delay_present_for_this_op {
                        // initial_display_delay_minus_1
                        bits.skip(4)?;
                    }
                }
            }
        }
        Ok(())
    }

    fn parse_frame_max_dimensions(&mut self, bits: &mut IBitStream) -> AvifResult<()> {
        let frame_width_bits_minus_1 = bits.read(4)?;
        let frame_height_bits_minus_1 = bits.read(4)?;
        let max_frame_width_minus_1 = bits.read(frame_width_bits_minus_1 as usize + 1)?;
        let max_frame_height_minus_1 = bits.read(frame_height_bits_minus_1 as usize + 1)?;
        self.max_width = checked_add!(max_frame_width_minus_1, 1)?;
        self.max_height = checked_add!(max_frame_height_minus_1, 1)?;
        let frame_id_numbers_present_flag =
            if self.reduced_still_picture_header { false } else { bits.read_bool()? };
        if frame_id_numbers_present_flag {
            // delta_frame_id_length_minus_2
            bits.skip(4)?;
            // additional_frame_id_length_minus_1
            bits.skip(3)?;
        }
        Ok(())
    }

    fn parse_enabled_features(&mut self, bits: &mut IBitStream) -> AvifResult<()> {
        // use_128x128_superblock
        bits.skip(1)?;
        // enable_filter_intra
        bits.skip(1)?;
        // enable_intra_edge_filter
        bits.skip(1)?;
        if self.reduced_still_picture_header {
            return Ok(());
        }
        // enable_interintra_compound
        bits.skip(1)?;
        // enable_masked_compound
        bits.skip(1)?;
        // enable_warped_motion
        bits.skip(1)?;
        // enable_dual_filter
        bits.skip(1)?;
        let enable_order_hint = bits.read_bool()?;
        if enable_order_hint {
            // enable_jnt_comp
            bits.skip(1)?;
            // enable_ref_frame_mvs
            bits.skip(1)?;
        }
        let seq_choose_screen_content_tools = bits.read_bool()?;
        let seq_force_screen_content_tools = if seq_choose_screen_content_tools {
            2 // SELECT_SCREEN_CONTENT_TOOLS
        } else {
            bits.read(1)?
        };
        if seq_force_screen_content_tools > 0 {
            let seq_choose_integer_mv = bits.read_bool()?;
            if !seq_choose_integer_mv {
                // seq_force_integer_mv
                bits.skip(1)?;
            }
        }
        if enable_order_hint {
            // order_hint_bits_minus_1
            bits.skip(3)?;
        }
        Ok(())
    }

    fn parse_color_config(&mut self, bits: &mut IBitStream) -> AvifResult<()> {
        self.config.high_bitdepth = bits.read_bool()?;
        if self.config.seq_profile == 2 && self.config.high_bitdepth {
            self.config.twelve_bit = bits.read_bool()?;
            self.bit_depth = if self.config.twelve_bit { 12 } else { 10 };
        } else {
            self.bit_depth = if self.config.high_bitdepth { 10 } else { 8 };
        }
        if self.config.seq_profile != 1 {
            self.config.monochrome = bits.read_bool()?;
        }
        let color_description_present_flag = bits.read_bool()?;
        if color_description_present_flag {
            self.color_primaries = (bits.read(8)? as u16).into();
            self.transfer_characteristics = (bits.read(8)? as u16).into();
            self.matrix_coefficients = (bits.read(8)? as u16).into();
        } else {
            self.color_primaries = ColorPrimaries::Unspecified;
            self.transfer_characteristics = TransferCharacteristics::Unspecified;
            self.matrix_coefficients = MatrixCoefficients::Unspecified;
        }
        if self.config.monochrome {
            let color_range = bits.read_bool()?;
            self.yuv_range = if color_range { YuvRange::Full } else { YuvRange::Limited };
            self.config.chroma_subsampling_x = 1;
            self.config.chroma_subsampling_y = 1;
            self.yuv_format = PixelFormat::Yuv400;
            return Ok(());
        } else if self.color_primaries == ColorPrimaries::Bt709
            && self.transfer_characteristics == TransferCharacteristics::Srgb
            && self.matrix_coefficients == MatrixCoefficients::Identity
        {
            self.yuv_range = YuvRange::Full;
            self.yuv_format = PixelFormat::Yuv444;
        } else {
            let color_range = bits.read_bool()?;
            self.yuv_range = if color_range { YuvRange::Full } else { YuvRange::Limited };
            match self.config.seq_profile {
                0 => {
                    self.config.chroma_subsampling_x = 1;
                    self.config.chroma_subsampling_y = 1;
                    self.yuv_format = PixelFormat::Yuv420;
                }
                1 => {
                    self.yuv_format = PixelFormat::Yuv444;
                }
                2 => {
                    if self.bit_depth == 12 {
                        self.config.chroma_subsampling_x = bits.read(1)? as u8;
                        if self.config.chroma_subsampling_x == 1 {
                            self.config.chroma_subsampling_y = bits.read(1)? as u8;
                        }
                    } else {
                        self.config.chroma_subsampling_x = 1;
                    }
                    self.yuv_format = if self.config.chroma_subsampling_x == 1 {
                        if self.config.chroma_subsampling_y == 1 {
                            PixelFormat::Yuv420
                        } else {
                            PixelFormat::Yuv422
                        }
                    } else {
                        PixelFormat::Yuv444
                    };
                }
                _ => {} // Not reached.
            }
            if self.config.chroma_subsampling_x == 1 && self.config.chroma_subsampling_y == 1 {
                self.config.chroma_sample_position = bits.read(2)?.into();
            }
        }
        // separate_uv_delta_q
        bits.skip(1)?;
        Ok(())
    }

    fn parse_obu_header(stream: &mut IStream) -> AvifResult<ObuHeader> {
        let mut bits = stream.sub_bit_stream(1)?;

        // Section 5.3.2 of AV1 specification.
        // https://aomediacodec.github.io/av1-spec/#obu-header-syntax
        let obu_forbidden_bit = bits.read(1)?;
        if obu_forbidden_bit != 0 {
            return Err(AvifError::BmffParseFailed(
                "invalid obu_forbidden_bit".into(),
            ));
        }
        let obu_type = bits.read(4)? as u8;
        let obu_extension_flag = bits.read_bool()?;
        let obu_has_size_field = bits.read_bool()?;
        // obu_reserved_1bit
        bits.skip(1)?; // "The value is ignored by a decoder."

        if obu_extension_flag {
            let mut bits = stream.sub_bit_stream(1)?;
            // temporal_id
            bits.skip(3)?;
            // spatial_id
            bits.skip(2)?;
            // extension_header_reserved_3bits
            bits.skip(3)?;
        }

        let size = if obu_has_size_field {
            stream.read_uleb128()?
        } else {
            u32_from_usize(stream.bytes_left()?)? // sz - 1 - obu_extension_flag
        };

        Ok(ObuHeader { obu_type, size })
    }

    pub(crate) fn parse_from_obus(data: &[u8]) -> AvifResult<Self> {
        let mut stream = IStream::create(data);

        while stream.has_bytes_left()? {
            let obu = Self::parse_obu_header(&mut stream)?;
            if obu.obu_type != /*OBU_SEQUENCE_HEADER=*/1 {
                // Not a sequence header. Skip this obu.
                stream.skip(usize_from_u32(obu.size)?)?;
                continue;
            }
            let mut bits = stream.sub_bit_stream(usize_from_u32(obu.size)?)?;
            let mut sequence_header = Av1SequenceHeader::default();
            sequence_header.parse_profile(&mut bits)?;
            sequence_header.parse_frame_max_dimensions(&mut bits)?;
            sequence_header.parse_enabled_features(&mut bits)?;
            // enable_superres
            bits.skip(1)?;
            // enable_cdef
            bits.skip(1)?;
            // enable_restoration
            bits.skip(1)?;
            sequence_header.parse_color_config(&mut bits)?;
            // film_grain_params_present
            bits.skip(1)?;
            return Ok(sequence_header);
        }
        Err(AvifError::BmffParseFailed(
            "could not parse sequence header".into(),
        ))
    }
}
