// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use fidl_fuchsia_media::FormatDetails;
use stream_processor_test::*;

/// Represents an H265 elementary stream.
pub struct H265Stream {
    data: Vec<u8>,
}

impl H265Stream {
    /// Adds data to raw H265 elementary stream
    pub fn append(&mut self, data: &mut Vec<u8>) {
        self.data.append(data);
    }

    /// Returns an iterator over H265 NALs that does not copy.
    pub fn nal_iter(&self) -> impl Iterator<Item = H265Nal<'_>> {
        H265NalIter { data: &self.data, pos: 0 }
    }
}

impl From<Vec<u8>> for H265Stream {
    fn from(data: Vec<u8>) -> Self {
        Self { data }
    }
}

impl ElementaryStream for H265Stream {
    fn format_details(&self, version_ordinal: u64) -> FormatDetails {
        FormatDetails {
            format_details_version_ordinal: Some(version_ordinal),
            mime_type: Some(String::from("video/h265")),
            ..Default::default()
        }
    }

    fn is_access_units(&self) -> bool {
        true
    }

    fn stream<'a>(&'a self) -> Box<dyn Iterator<Item = ElementaryStreamChunk> + 'a> {
        Box::new(self.nal_iter().map(|nal| ElementaryStreamChunk {
            start_access_unit: true,
            known_end_access_unit: true,
            data: nal.data.to_vec(),
            significance: match nal.kind {
                H265NalKind::IRAP | H265NalKind::NonIRAP => {
                    Significance::Video(VideoSignificance::Picture)
                }
                _ => Significance::Video(VideoSignificance::NotPicture),
            },
            timestamp: None,
        }))
    }
}

#[derive(Debug)]
pub struct H265Nal<'a> {
    pub kind: H265NalKind,
    pub data: &'a [u8],
}

#[derive(Debug, Clone, PartialEq)]
pub enum H265NalKind {
    IRAP,
    NonIRAP,
    VPS,
    SPS,
    PPS,
    Unknown,
}

const IDR_W_RADL_CODE: u8 = 19;
const CRA_NUT_CODE: u8 = 21;
const VPS_CODE: u8 = 32;
const SPS_CODE: u8 = 33;
const PPS_CODE: u8 = 34;
const TRAIL_R_CODE: u8 = 1;

impl H265NalKind {
    fn from_header(header: u8) -> Self {
        let kind = (header >> 1) & 0x3f;
        match kind {
            kind if kind == IDR_W_RADL_CODE => H265NalKind::IRAP,
            kind if kind == CRA_NUT_CODE => H265NalKind::IRAP,
            kind if kind == VPS_CODE => H265NalKind::VPS,
            kind if kind == SPS_CODE => H265NalKind::SPS,
            kind if kind == PPS_CODE => H265NalKind::PPS,
            kind if kind == TRAIL_R_CODE => H265NalKind::NonIRAP,
            _ => H265NalKind::Unknown,
        }
    }
}

struct H265NalStart<'a> {
    /// Position in the h265 stream of the start.
    pos: usize,
    /// All the data from the start of the NAL onward.
    data: &'a [u8],
    kind: H265NalKind,
}

/// An iterator over NALs in an H265 stream.
struct H265NalIter<'a> {
    data: &'a [u8],
    pos: usize,
}

impl<'a> H265NalIter<'a> {
    fn next_nal(&self, pos: usize) -> Option<H265Nal<'a>> {
        // This won't need to search if pos already at a start code.
        let nal_start = self.next_nal_start(pos)?;
        // We search 3 bytes after the found nal's start, because that will
        // ensure we don't just find the same start code again.
        match self.next_nal_start(nal_start.pos + 3) {
            Some(next_start) => Some(H265Nal {
                kind: nal_start.kind,
                data: &nal_start.data[0..(next_start.pos - nal_start.pos)],
            }),
            None => Some(H265Nal { kind: nal_start.kind, data: nal_start.data }),
        }
    }

    fn next_nal_start(&self, pos: usize) -> Option<H265NalStart<'a>> {
        // This search size will find 3 and 4 byte start codes, and the
        // header value.
        const NAL_SEARCH_SIZE: usize = 5;

        let data = self.data.get(pos..)?;
        data.windows(NAL_SEARCH_SIZE).enumerate().find_map(|(i, candidate)| match candidate {
            [0, 0, 0, 1, h] | [0, 0, 1, h, _] => Some(H265NalStart {
                pos: i + pos,
                data: data.get(i..).expect("Getting slice starting where we just matched"),
                kind: H265NalKind::from_header(*h),
            }),
            _ => None,
        })
    }
}

impl<'a> Iterator for H265NalIter<'a> {
    type Item = H265Nal<'a>;
    fn next(&mut self) -> Option<Self::Item> {
        let nal = self.next_nal(self.pos);
        self.pos += nal.as_ref().map(|n| n.data.len()).unwrap_or(0);
        nal
    }
}
