// Copyright 2023 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_starnix_gralloc as fgralloc;
use starnix_core::mm::MemoryAccessorExt;
use starnix_core::task::CurrentTask;
use starnix_core::vfs::{
    FileObject, FileOps, InputBuffer, OutputBuffer, SeekTarget, fileops_impl_noop_sync,
};
use starnix_logging::{log_error, log_info, track_stub};
use starnix_sync::{FileOpsCore, Locked, Unlocked};
use starnix_syscalls::{SUCCESS, SyscallArg, SyscallResult};
use starnix_uapi::errors::Errno;
use starnix_uapi::user_address::{UserAddress, UserRef};
use starnix_uapi::{errno, error};
use virtgralloc::{
    VIRTGRALLOC_IOCTL_SET_VULKAN_MODE, VIRTGRALLOC_SET_VULKAN_MODE_RESULT_SUCCESS,
    virtgralloc_SetVulkanModeResult, virtgralloc_VulkanMode, virtgralloc_set_vulkan_mode,
};

pub struct GrallocFile {
    mode_setter: fgralloc::VulkanModeSetterSynchronousProxy,
}

impl GrallocFile {
    pub fn new_file(current_task: &CurrentTask) -> Result<Box<dyn FileOps>, Errno> {
        let mode_setter = current_task
            .kernel()
            .connect_to_protocol_at_container_svc::<fgralloc::VulkanModeSetterMarker>()
            .expect("gralloc feature requires fuchsia.starnix.gralloc.VulkanModeSetter protocol in container /svc dir, and a corresponding server")
            .into_sync_proxy();
        Ok(Box::new(Self { mode_setter }))
    }

    fn set_vulkan_mode(
        &self,
        vulkan_mode: virtgralloc_VulkanMode,
    ) -> Result<virtgralloc_SetVulkanModeResult, Errno> {
        let vulkan_mode = fgralloc::VulkanMode::from_primitive(vulkan_mode as u32)
            .ok_or_else(|| errno!(EINVAL))
            .map_err(|e| {
                log_error!("VulkanMode::from_primitive failed");
                e
            })?;

        // The SetVulkanMode FIDL call must complete before the IOCTL can complete, but we don't
        // need to hold the lock the whole time, just to start the request. We don't actually expect
        // more than up to one call to this IOCTL per container boot, but nice to avoid holding the
        // lock for any longer than necessary.
        //
        // This must work, since this is the only way that gralloc will know which vulkan impl,
        // which is necessary for gralloc to work properly, and the gralloc feature requires gralloc
        // to work properly. There's no meaningful way for the IOCTL caller to handle an IOCTL
        // failure other than just logging and then ignoring it, which would only make the overall
        // broken situation more confusing that just using expect() here. Under normal operation,
        // this is only called once early in boot.
        self.mode_setter
            .set_vulkan_mode(
                &fgralloc::VulkanModeSetterSetVulkanModeRequest {
                    vulkan_mode: Some(vulkan_mode),
                    ..Default::default()
                },
                zx::MonotonicInstant::INFINITE,
            )
            .expect("gralloc feature requires working VulkanModeSetter")
            .expect("gralloc feature requires VulkanModeSetter to set mode");

        log_info!("gralloc vulkan_mode set to {:?}", vulkan_mode);

        Ok(VIRTGRALLOC_SET_VULKAN_MODE_RESULT_SUCCESS)
    }
}

impl FileOps for GrallocFile {
    fileops_impl_noop_sync!();

    fn is_seekable(&self) -> bool {
        false
    }

    fn seek(
        &self,
        _locked: &mut Locked<FileOpsCore>,
        _file: &FileObject,
        _current_task: &CurrentTask,
        _current_offset: starnix_uapi::off_t,
        _target: SeekTarget,
    ) -> Result<starnix_uapi::off_t, starnix_uapi::errors::Errno> {
        error!(ESPIPE)
    }

    fn ioctl(
        &self,
        _locked: &mut Locked<Unlocked>,
        _file: &FileObject,
        current_task: &CurrentTask,
        request: u32,
        arg: SyscallArg,
    ) -> Result<SyscallResult, Errno> {
        match request {
            VIRTGRALLOC_IOCTL_SET_VULKAN_MODE => {
                // switch from map_err to inspect_err when/if stable
                let user_addr = UserAddress::from(arg);
                let mut request: virtgralloc_set_vulkan_mode =
                    current_task.read_object(UserRef::new(user_addr)).map_err(|e| {
                        log_error!("virtgralloc_request_SetVulkanMode read_object failed: {:?}", e);
                        e
                    })?;
                request.result = self.set_vulkan_mode(request.vulkan_mode).map_err(|e| {
                    log_error!("set_vulkan_mode failed: {:?}", e);
                    e
                })?;
                current_task.write_object(UserRef::new(user_addr), &request)
            }
            unknown_ioctl => {
                track_stub!(TODO("https://fxbug.dev/322874368"), "gralloc ioctl", unknown_ioctl);
                error!(ENOSYS)
            }
        }?;

        Ok(SUCCESS)
    }

    fn read(
        &self,
        _locked: &mut Locked<FileOpsCore>,
        _file: &FileObject,
        _current_task: &CurrentTask,
        offset: usize,
        _data: &mut dyn OutputBuffer,
    ) -> Result<usize, Errno> {
        // because fileops_impl_nonseekable!()
        debug_assert!(offset == 0);
        error!(EINVAL)
    }

    fn write(
        &self,
        _locked: &mut Locked<FileOpsCore>,
        _file: &FileObject,
        _current_task: &CurrentTask,
        offset: usize,
        _data: &mut dyn InputBuffer,
    ) -> Result<usize, Errno> {
        // because fileops_impl_nonseekable!()
        debug_assert!(offset == 0);
        error!(EINVAL)
    }
}
