// SPDX-License-Identifier: GPL-2.0

// Copyright (C) 2025 Google LLC.

//! Sample DebugFS exporting platform driver
//!
//! To successfully probe this driver with ACPI, use an ssdt that looks like
//!
//! ```dsl
//! DefinitionBlock ("", "SSDT", 2, "TEST", "VIRTACPI", 0x00000001)
//! {
//!    Scope (\_SB)
//!    {
//!        Device (T432)
//!        {
//!            Name (_HID, "LNUXBEEF")  // ACPI hardware ID to match
//!            Name (_UID, 1)
//!            Name (_STA, 0x0F)        // Device present, enabled
//!            Name (_DSD, Package () { // Sample attribute
//!                ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"),
//!                Package() {
//!                    Package(2) {"compatible", "sample-debugfs"}
//!                }
//!            })
//!            Name (_CRS, ResourceTemplate ()
//!            {
//!                Memory32Fixed (ReadWrite, 0xFED00000, 0x1000)
//!            })
//!        }
//!    }
//! }
//! ```

use core::str::FromStr;
use kernel::c_str;
use kernel::debugfs::{Dir, File};
use kernel::new_mutex;
use kernel::prelude::*;
use kernel::sizes::*;
use kernel::sync::atomic::{Atomic, Relaxed};
use kernel::sync::Mutex;
use kernel::{acpi, device::Core, of, platform, str::CString, types::ARef};

kernel::module_platform_driver! {
    type: RustDebugFs,
    name: "rust_debugfs",
    authors: ["Matthew Maurer"],
    description: "Rust DebugFS usage sample",
    license: "GPL",
}

#[pin_data]
struct RustDebugFs {
    pdev: ARef<platform::Device>,
    // As we only hold these for drop effect (to remove the directory/files) we have a leading
    // underscore to indicate to the compiler that we don't expect to use this field directly.
    _debugfs: Dir,
    #[pin]
    _compatible: File<CString>,
    #[pin]
    counter: File<Atomic<usize>>,
    #[pin]
    inner: File<Mutex<Inner>>,
    #[pin]
    array_blob: File<Mutex<[u8; 4]>>,
    #[pin]
    vector_blob: File<Mutex<KVec<u8>>>,
}

#[derive(Debug)]
struct Inner {
    x: u32,
    y: u32,
}

impl FromStr for Inner {
    type Err = Error;
    fn from_str(s: &str) -> Result<Self> {
        let mut parts = s.split_whitespace();
        let x = parts
            .next()
            .ok_or(EINVAL)?
            .parse::<u32>()
            .map_err(|_| EINVAL)?;
        let y = parts
            .next()
            .ok_or(EINVAL)?
            .parse::<u32>()
            .map_err(|_| EINVAL)?;
        if parts.next().is_some() {
            return Err(EINVAL);
        }
        Ok(Inner { x, y })
    }
}

kernel::acpi_device_table!(
    ACPI_TABLE,
    MODULE_ACPI_TABLE,
    <RustDebugFs as platform::Driver>::IdInfo,
    [(acpi::DeviceId::new(c_str!("LNUXBEEF")), ())]
);

impl platform::Driver for RustDebugFs {
    type IdInfo = ();
    const OF_ID_TABLE: Option<of::IdTable<Self::IdInfo>> = None;
    const ACPI_ID_TABLE: Option<acpi::IdTable<Self::IdInfo>> = Some(&ACPI_TABLE);

    fn probe(
        pdev: &platform::Device<Core>,
        _info: Option<&Self::IdInfo>,
    ) -> impl PinInit<Self, Error> {
        RustDebugFs::new(pdev).pin_chain(|this| {
            this.counter.store(91, Relaxed);
            {
                let mut guard = this.inner.lock();
                guard.x = guard.y;
                guard.y = 42;
            }

            Ok(())
        })
    }
}

impl RustDebugFs {
    fn build_counter(dir: &Dir) -> impl PinInit<File<Atomic<usize>>> + '_ {
        dir.read_write_file(c_str!("counter"), Atomic::<usize>::new(0))
    }

    fn build_inner(dir: &Dir) -> impl PinInit<File<Mutex<Inner>>> + '_ {
        dir.read_write_file(c_str!("pair"), new_mutex!(Inner { x: 3, y: 10 }))
    }

    fn new(pdev: &platform::Device<Core>) -> impl PinInit<Self, Error> + '_ {
        let debugfs = Dir::new(c_str!("sample_debugfs"));
        let dev = pdev.as_ref();

        try_pin_init! {
            Self {
                _compatible <- debugfs.read_only_file(
                    c_str!("compatible"),
                    dev.fwnode()
                        .ok_or(ENOENT)?
                        .property_read::<CString>(c_str!("compatible"))
                        .required_by(dev)?,
                ),
                counter <- Self::build_counter(&debugfs),
                inner <- Self::build_inner(&debugfs),
                array_blob <- debugfs.read_write_binary_file(
                    c_str!("array_blob"),
                    new_mutex!([0x62, 0x6c, 0x6f, 0x62]),
                ),
                vector_blob <- debugfs.read_write_binary_file(
                    c_str!("vector_blob"),
                    new_mutex!(kernel::kvec!(0x42; SZ_4K)?),
                ),
                _debugfs: debugfs,
                pdev: pdev.into(),
            }
        }
    }
}
