// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2024 Google LLC.

//! Rust misc device sample.
//!
//! Below is an example userspace C program that exercises this sample's functionality.
//!
//! ```c
//! #include <stdio.h>
//! #include <stdlib.h>
//! #include <errno.h>
//! #include <fcntl.h>
//! #include <unistd.h>
//! #include <sys/ioctl.h>
//!
//! #define RUST_MISC_DEV_FAIL _IO('|', 0)
//! #define RUST_MISC_DEV_HELLO _IO('|', 0x80)
//! #define RUST_MISC_DEV_GET_VALUE _IOR('|', 0x81, int)
//! #define RUST_MISC_DEV_SET_VALUE _IOW('|', 0x82, int)
//!
//! int main() {
//!   int value, new_value;
//!   int fd, ret;
//!
//!   // Open the device file
//!   printf("Opening /dev/rust-misc-device for reading and writing\n");
//!   fd = open("/dev/rust-misc-device", O_RDWR);
//!   if (fd < 0) {
//!     perror("open");
//!     return errno;
//!   }
//!
//!   // Make call into driver to say "hello"
//!   printf("Calling Hello\n");
//!   ret = ioctl(fd, RUST_MISC_DEV_HELLO, NULL);
//!   if (ret < 0) {
//!     perror("ioctl: Failed to call into Hello");
//!     close(fd);
//!     return errno;
//!   }
//!
//!   // Get initial value
//!   printf("Fetching initial value\n");
//!   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &value);
//!   if (ret < 0) {
//!     perror("ioctl: Failed to fetch the initial value");
//!     close(fd);
//!     return errno;
//!   }
//!
//!   value++;
//!
//!   // Set value to something different
//!   printf("Submitting new value (%d)\n", value);
//!   ret = ioctl(fd, RUST_MISC_DEV_SET_VALUE, &value);
//!   if (ret < 0) {
//!     perror("ioctl: Failed to submit new value");
//!     close(fd);
//!     return errno;
//!   }
//!
//!   // Ensure new value was applied
//!   printf("Fetching new value\n");
//!   ret = ioctl(fd, RUST_MISC_DEV_GET_VALUE, &new_value);
//!   if (ret < 0) {
//!     perror("ioctl: Failed to fetch the new value");
//!     close(fd);
//!     return errno;
//!   }
//!
//!   if (value != new_value) {
//!     printf("Failed: Committed and retrieved values are different (%d - %d)\n", value, new_value);
//!     close(fd);
//!     return -1;
//!   }
//!
//!   // Call the unsuccessful ioctl
//!   printf("Attempting to call in to an non-existent IOCTL\n");
//!   ret = ioctl(fd, RUST_MISC_DEV_FAIL, NULL);
//!   if (ret < 0) {
//!     perror("ioctl: Succeeded to fail - this was expected");
//!   } else {
//!     printf("ioctl: Failed to fail\n");
//!     close(fd);
//!     return -1;
//!   }
//!
//!   // Close the device file
//!   printf("Closing /dev/rust-misc-device\n");
//!   close(fd);
//!
//!   printf("Success\n");
//!   return 0;
//! }
//! ```

use core::pin::Pin;

use kernel::{
    c_str,
    device::Device,
    fs::File,
    ioctl::{_IO, _IOC_SIZE, _IOR, _IOW},
    miscdevice::{MiscDevice, MiscDeviceOptions, MiscDeviceRegistration},
    new_mutex,
    prelude::*,
    sync::Mutex,
    types::ARef,
    uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
};

const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
const RUST_MISC_DEV_GET_VALUE: u32 = _IOR::<i32>('|' as u32, 0x81);
const RUST_MISC_DEV_SET_VALUE: u32 = _IOW::<i32>('|' as u32, 0x82);

module! {
    type: RustMiscDeviceModule,
    name: "rust_misc_device",
    authors: ["Lee Jones"],
    description: "Rust misc device sample",
    license: "GPL",
}

#[pin_data]
struct RustMiscDeviceModule {
    #[pin]
    _miscdev: MiscDeviceRegistration<RustMiscDevice>,
}

impl kernel::InPlaceModule for RustMiscDeviceModule {
    fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
        pr_info!("Initialising Rust Misc Device Sample\n");

        let options = MiscDeviceOptions {
            name: c_str!("rust-misc-device"),
        };

        try_pin_init!(Self {
            _miscdev <- MiscDeviceRegistration::register(options),
        })
    }
}

struct Inner {
    value: i32,
}

#[pin_data(PinnedDrop)]
struct RustMiscDevice {
    #[pin]
    inner: Mutex<Inner>,
    dev: ARef<Device>,
}

#[vtable]
impl MiscDevice for RustMiscDevice {
    type Ptr = Pin<KBox<Self>>;

    fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Self>>> {
        let dev = ARef::from(misc.device());

        dev_info!(dev, "Opening Rust Misc Device Sample\n");

        KBox::try_pin_init(
            try_pin_init! {
                RustMiscDevice {
                    inner <- new_mutex!( Inner{ value: 0_i32 } ),
                    dev: dev,
                }
            },
            GFP_KERNEL,
        )
    }

    fn ioctl(me: Pin<&RustMiscDevice>, _file: &File, cmd: u32, arg: usize) -> Result<isize> {
        dev_info!(me.dev, "IOCTLing Rust Misc Device Sample\n");

        let size = _IOC_SIZE(cmd);

        match cmd {
            RUST_MISC_DEV_GET_VALUE => me.get_value(UserSlice::new(arg, size).writer())?,
            RUST_MISC_DEV_SET_VALUE => me.set_value(UserSlice::new(arg, size).reader())?,
            RUST_MISC_DEV_HELLO => me.hello()?,
            _ => {
                dev_err!(me.dev, "-> IOCTL not recognised: {}\n", cmd);
                return Err(ENOTTY);
            }
        };

        Ok(0)
    }
}

#[pinned_drop]
impl PinnedDrop for RustMiscDevice {
    fn drop(self: Pin<&mut Self>) {
        dev_info!(self.dev, "Exiting the Rust Misc Device Sample\n");
    }
}

impl RustMiscDevice {
    fn set_value(&self, mut reader: UserSliceReader) -> Result<isize> {
        let new_value = reader.read::<i32>()?;
        let mut guard = self.inner.lock();

        dev_info!(
            self.dev,
            "-> Copying data from userspace (value: {})\n",
            new_value
        );

        guard.value = new_value;
        Ok(0)
    }

    fn get_value(&self, mut writer: UserSliceWriter) -> Result<isize> {
        let guard = self.inner.lock();
        let value = guard.value;

        // Free-up the lock and use our locally cached instance from here
        drop(guard);

        dev_info!(
            self.dev,
            "-> Copying data to userspace (value: {})\n",
            &value
        );

        writer.write::<i32>(&value)?;
        Ok(0)
    }

    fn hello(&self) -> Result<isize> {
        dev_info!(self.dev, "-> Hello from the Rust Misc Device\n");

        Ok(0)
    }
}
