// 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::*;

#[derive(Clone, Copy, Debug)]
pub struct PointerSlice<T> {
    ptr: *mut [T],
}

impl<T> PointerSlice<T> {
    /// # Safety
    /// `ptr` must live at least as long as the struct, and not be accessed other than through this
    /// struct. It must point to a memory region of at least `size` elements.
    pub unsafe fn create(ptr: *mut T, size: usize) -> AvifResult<Self> {
        if ptr.is_null() || size == 0 {
            return Err(AvifError::NoContent);
        }
        // Ensure that size does not exceed isize::MAX.
        let _ = isize_from_usize(size)?;
        Ok(Self {
            ptr: unsafe { std::slice::from_raw_parts_mut(ptr, size) },
        })
    }

    fn slice_impl(&self) -> &[T] {
        // SAFETY: We only construct this with `ptr` which is valid at least as long as this struct
        // is alive, and ro/mut borrows of the whole struct to access the inner slice, which makes
        // our access appropriately exclusive.
        unsafe { &(*self.ptr) }
    }

    fn slice_impl_mut(&mut self) -> &mut [T] {
        // SAFETY: We only construct this with `ptr` which is valid at least as long as this struct
        // is alive, and ro/mut borrows of the whole struct to access the inner slice, which makes
        // our access appropriately exclusive.
        unsafe { &mut (*self.ptr) }
    }

    pub fn slice(&self, range: Range<usize>) -> AvifResult<&[T]> {
        let data = self.slice_impl();
        check_slice_range(data.len(), &range)?;
        Ok(&data[range])
    }

    pub fn slice_mut(&mut self, range: Range<usize>) -> AvifResult<&mut [T]> {
        let data = self.slice_impl_mut();
        check_slice_range(data.len(), &range)?;
        Ok(&mut data[range])
    }

    pub fn ptr(&self) -> *const T {
        self.slice_impl().as_ptr()
    }

    pub fn ptr_mut(&mut self) -> *mut T {
        self.slice_impl_mut().as_mut_ptr()
    }

    pub fn is_empty(&self) -> bool {
        self.slice_impl().is_empty()
    }
}

// This struct must not be derived from the default `Clone` trait as it has to be cloned with error
// checking using the `try_clone` function.
#[derive(Debug)]
pub enum Pixels {
    // Intended for holding data from underlying native libraries. Used for 8-bit images.
    Pointer(PointerSlice<u8>),
    // Intended for holding data from underlying native libraries. Used for 10-bit, 12-bit and
    // 16-bit images.
    Pointer16(PointerSlice<u16>),
    // Used for 8-bit images.
    Buffer(Vec<u8>),
    // Used for 10-bit, 12-bit and 16-bit images.
    Buffer16(Vec<u16>),
}

impl Pixels {
    pub fn from_raw_pointer(
        ptr: *mut u8,
        depth: u32,
        height: u32,
        mut row_bytes: u32,
    ) -> AvifResult<Self> {
        if depth > 8 {
            row_bytes /= 2;
        }
        let size = usize_from_u32(checked_mul!(height, row_bytes)?)?;
        if depth > 8 {
            Ok(Pixels::Pointer16(unsafe {
                PointerSlice::create(ptr as *mut u16, size)?
            }))
        } else {
            Ok(Pixels::Pointer(unsafe { PointerSlice::create(ptr, size)? }))
        }
    }

    pub fn size(&self) -> usize {
        match self {
            Pixels::Pointer(_) => 0,
            Pixels::Pointer16(_) => 0,
            Pixels::Buffer(buffer) => buffer.len(),
            Pixels::Buffer16(buffer) => buffer.len(),
        }
    }

    pub(crate) fn pixel_bit_size(&self) -> usize {
        match self {
            Pixels::Pointer(_) => 0,
            Pixels::Pointer16(_) => 0,
            Pixels::Buffer(_) => 8,
            Pixels::Buffer16(_) => 16,
        }
    }

    pub(crate) fn has_data(&self) -> bool {
        match self {
            Pixels::Pointer(ptr) => !ptr.is_empty(),
            Pixels::Pointer16(ptr) => !ptr.is_empty(),
            Pixels::Buffer(buffer) => !buffer.is_empty(),
            Pixels::Buffer16(buffer) => !buffer.is_empty(),
        }
    }

    pub(crate) fn resize(&mut self, size: usize, default: u16) -> AvifResult<()> {
        match self {
            Pixels::Pointer(_) => return Err(AvifError::InvalidArgument),
            Pixels::Pointer16(_) => return Err(AvifError::InvalidArgument),
            Pixels::Buffer(buffer) => {
                if buffer.capacity() < size && buffer.try_reserve_exact(size).is_err() {
                    return Err(AvifError::OutOfMemory);
                }
                buffer.resize(size, default as u8);
            }
            Pixels::Buffer16(buffer) => {
                if buffer.capacity() < size && buffer.try_reserve_exact(size).is_err() {
                    return Err(AvifError::OutOfMemory);
                }
                buffer.resize(size, default);
            }
        }
        Ok(())
    }

    pub(crate) fn is_pointer(&self) -> bool {
        matches!(self, Pixels::Pointer(_) | Pixels::Pointer16(_))
    }

    pub fn ptr(&self) -> *const u8 {
        match self {
            Pixels::Pointer(ptr) => ptr.ptr(),
            Pixels::Buffer(buffer) => buffer.as_ptr(),
            _ => std::ptr::null_mut(),
        }
    }

    pub fn ptr16(&self) -> *const u16 {
        match self {
            Pixels::Pointer16(ptr) => ptr.ptr(),
            Pixels::Buffer16(buffer) => buffer.as_ptr(),
            _ => std::ptr::null_mut(),
        }
    }

    pub fn ptr_mut(&mut self) -> *mut u8 {
        match self {
            Pixels::Pointer(ptr) => ptr.ptr_mut(),
            Pixels::Buffer(buffer) => buffer.as_mut_ptr(),
            _ => std::ptr::null_mut(),
        }
    }

    pub fn ptr16_mut(&mut self) -> *mut u16 {
        match self {
            Pixels::Pointer16(ptr) => ptr.ptr_mut(),
            Pixels::Buffer16(buffer) => buffer.as_mut_ptr(),
            _ => std::ptr::null_mut(),
        }
    }

    pub(crate) fn try_clone(&self) -> AvifResult<Pixels> {
        match self {
            Pixels::Pointer(ptr) => Ok(Pixels::Pointer(*ptr)),
            Pixels::Pointer16(ptr) => Ok(Pixels::Pointer16(*ptr)),
            Pixels::Buffer(buffer) => {
                let mut cloned_buffer: Vec<u8> = vec![];
                cloned_buffer
                    .try_reserve_exact(buffer.len())
                    .or(Err(AvifError::OutOfMemory))?;
                cloned_buffer.extend_from_slice(buffer);
                Ok(Pixels::Buffer(cloned_buffer))
            }
            Pixels::Buffer16(buffer16) => {
                let mut cloned_buffer16: Vec<u16> = vec![];
                cloned_buffer16
                    .try_reserve_exact(buffer16.len())
                    .or(Err(AvifError::OutOfMemory))?;
                cloned_buffer16.extend_from_slice(buffer16);
                Ok(Pixels::Buffer16(cloned_buffer16))
            }
        }
    }

    pub fn slice(&self, offset: u32, size: u32) -> AvifResult<&[u8]> {
        let offset: usize = usize_from_u32(offset)?;
        let size: usize = usize_from_u32(size)?;
        match self {
            Pixels::Pointer(ptr) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                ptr.slice(offset..end)
            }
            Pixels::Pointer16(_) => Err(AvifError::NoContent),
            Pixels::Buffer(buffer) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                let range = offset..end;
                check_slice_range(buffer.len(), &range)?;
                Ok(&buffer[range])
            }
            Pixels::Buffer16(_) => Err(AvifError::NoContent),
        }
    }

    pub fn slice_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u8]> {
        let offset: usize = usize_from_u32(offset)?;
        let size: usize = usize_from_u32(size)?;
        match self {
            Pixels::Pointer(ptr) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                ptr.slice_mut(offset..end)
            }
            Pixels::Pointer16(_) => Err(AvifError::NoContent),
            Pixels::Buffer(buffer) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                let range = offset..end;
                check_slice_range(buffer.len(), &range)?;
                Ok(&mut buffer[range])
            }
            Pixels::Buffer16(_) => Err(AvifError::NoContent),
        }
    }

    pub fn slice16(&self, offset: u32, size: u32) -> AvifResult<&[u16]> {
        let offset: usize = usize_from_u32(offset)?;
        let size: usize = usize_from_u32(size)?;
        match self {
            Pixels::Pointer(_) => Err(AvifError::NoContent),
            Pixels::Pointer16(ptr) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                ptr.slice(offset..end)
            }
            Pixels::Buffer(_) => Err(AvifError::NoContent),
            Pixels::Buffer16(buffer) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                let range = offset..end;
                check_slice_range(buffer.len(), &range)?;
                Ok(&buffer[range])
            }
        }
    }

    pub fn slice16_mut(&mut self, offset: u32, size: u32) -> AvifResult<&mut [u16]> {
        let offset: usize = usize_from_u32(offset)?;
        let size: usize = usize_from_u32(size)?;
        match self {
            Pixels::Pointer(_) => Err(AvifError::NoContent),
            Pixels::Pointer16(ptr) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                ptr.slice_mut(offset..end)
            }
            Pixels::Buffer(_) => Err(AvifError::NoContent),
            Pixels::Buffer16(buffer) => {
                let end = offset.checked_add(size).ok_or(AvifError::NoContent)?;
                let range = offset..end;
                check_slice_range(buffer.len(), &range)?;
                Ok(&mut buffer[range])
            }
        }
    }
}
