//! Linux ARM64 设备后端实现
//!
//! 支持 Linux ARM64 平台的设备操作，包括显示信息、背光控制、防息屏等功能。

use crate::core::message::{DeviceCapability, DeviceCommand, DeviceResponse, PixelFormat};
use crate::plugins::device::backend::DeviceBackend;
use anyhow::Result;
use std::fs;
use std::process::{Child, Command, Stdio};

/// Linux ARM64 设备后端
///
/// 通过 sysfs 和 systemd-inhibit 实现设备控制。
pub struct LinuxArm64Backend {
    /// systemd-inhibit 子进程（用于防息屏）
    wake_lock_child: Option<Child>,
    /// unclutter 子进程（用于隐藏光标）
    cursor_child: Option<Child>,
    /// 显示宽度
    display_width: u32,
    /// 显示高度
    display_height: u32,
    /// 背光状态
    backlight_enabled: bool,
}

impl Default for LinuxArm64Backend {
    fn default() -> Self {
        Self::new()
    }
}

impl LinuxArm64Backend {
    /// 创建新的 Linux ARM64 后端实例
    pub fn new() -> Self {
        Self {
            wake_lock_child: None,
            cursor_child: None,
            display_width: 1920, // 默认分辨率
            display_height: 1080,
            backlight_enabled: true,
        }
    }

    /// 读取 framebuffer 分辨率
    fn read_framebuffer_resolution(&mut self) -> Result<()> {
        // 尝试从 /sys/class/graphics/fb0/virtual_size 读取分辨率
        if let Ok(content) = fs::read_to_string("/sys/class/graphics/fb0/virtual_size") {
            let parts: Vec<&str> = content.trim().split(',').collect();
            if parts.len() == 2 {
                if let (Ok(width), Ok(height)) = (parts[0].parse(), parts[1].parse()) {
                    self.display_width = width;
                    self.display_height = height;
                    return Ok(());
                }
            }
        }

        // 如果读取失败，使用默认值（已在 new() 中设置）
        Ok(())
    }

    /// 启动防息屏（systemd-inhibit）
    fn start_sleep_inhibit(&mut self) -> Result<()> {
        if self.wake_lock_child.is_some() {
            return Ok(());
        }

        match Command::new("systemd-inhibit")
            .arg("--what=idle:sleep")
            .arg("--mode=block")
            .arg("--who=ShowenV2")
            .arg("--why=Device operation in progress")
            .arg("sleep")
            .arg("infinity")
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .spawn()
        {
            Ok(child) => {
                self.wake_lock_child = Some(child);
                Ok(())
            }
            Err(e) => Err(anyhow::anyhow!("Failed to start systemd-inhibit: {}", e)),
        }
    }

    /// 停止防息屏
    fn stop_sleep_inhibit(&mut self) -> Result<()> {
        if let Some(mut child) = self.wake_lock_child.take() {
            child.kill()?;
            child.wait()?;
        }
        Ok(())
    }

    /// 设置背光状态
    fn set_backlight(&mut self, enabled: bool) -> Result<()> {
        self.backlight_enabled = enabled;

        // 尝试写入 /sys/class/backlight/*/brightness
        // 首先查找 backlight 设备
        if let Ok(entries) = fs::read_dir("/sys/class/backlight") {
            for entry in entries.flatten() {
                let brightness_path = entry.path().join("brightness");
                let max_brightness_path = entry.path().join("max_brightness");

                // 读取最大亮度
                if let Ok(max_str) = fs::read_to_string(&max_brightness_path) {
                    if let Ok(max_brightness) = max_str.trim().parse::<u32>() {
                        // 设置亮度：开启时设为最大值，关闭时设为 0
                        let value = if enabled { max_brightness } else { 0 };
                        if fs::write(&brightness_path, value.to_string()).is_ok() {
                            return Ok(());
                        }
                    }
                }
            }
        }

        // 如果没有找到 backlight 设备，返回成功（某些设备可能不支持）
        Ok(())
    }

    /// 设置光标可见性
    fn set_cursor_visible(&mut self, visible: bool) -> Result<()> {
        if visible {
            // 显示光标：停止 unclutter 进程
            if self.cursor_child.is_some() {
                // 先清理已有的 cursor_child
                if let Some(mut child) = self.cursor_child.take() {
                    let _ = child.kill();
                    let _ = child.wait();
                }
            }

            // 使用 pkill 确保清理所有 unclutter 进程
            let _ = Command::new("pkill")
                .args(["-f", "unclutter"])
                .stdin(Stdio::null())
                .stdout(Stdio::null())
                .stderr(Stdio::null())
                .status();
        } else {
            // 隐藏光标：启动 unclutter 进程
            if self.cursor_child.is_some() {
                // 已经隐藏，无需重复操作
                return Ok(());
            }

            // 先清理旧的 unclutter 进程
            let _ = Command::new("pkill")
                .args(["-f", "unclutter"])
                .stdin(Stdio::null())
                .stdout(Stdio::null())
                .stderr(Stdio::null())
                .status();

            // 启动 unclutter 进程
            match Command::new("unclutter")
                .arg("-idle")
                .arg("0")
                .arg("-root")
                .stdin(Stdio::null())
                .stdout(Stdio::null())
                .stderr(Stdio::null())
                .spawn()
            {
                Ok(child) => {
                    self.cursor_child = Some(child);
                }
                Err(e) => {
                    // unclutter 不可用时记录警告但不阻塞
                    eprintln!(
                        "[LinuxArm64Backend] Warning: Failed to start unclutter: {}",
                        e
                    );
                }
            }
        }

        Ok(())
    }
}

impl DeviceBackend for LinuxArm64Backend {
    fn name(&self) -> &str {
        "linux-arm64"
    }

    fn init(&mut self, _config: &serde_json::Value) -> Result<()> {
        // 读取 framebuffer 分辨率
        self.read_framebuffer_resolution()?;
        Ok(())
    }

    fn capabilities(&self) -> Vec<DeviceCapability> {
        vec![
            DeviceCapability::Display,
            DeviceCapability::Backlight,
            DeviceCapability::Framebuffer,
            DeviceCapability::Cursor,
        ]
    }

    fn handle_command(&mut self, cmd: DeviceCommand) -> Result<DeviceResponse> {
        match cmd {
            DeviceCommand::GetDisplayInfo => Ok(DeviceResponse::DisplayInfo {
                width: self.display_width,
                height: self.display_height,
                format: PixelFormat::RGB888,
            }),

            DeviceCommand::SetSleepInhibit(enable) => {
                if enable {
                    self.start_sleep_inhibit()?;
                } else {
                    self.stop_sleep_inhibit()?;
                }
                Ok(DeviceResponse::Ok)
            }

            DeviceCommand::SetBacklight(enabled) => {
                self.set_backlight(enabled)?;
                Ok(DeviceResponse::Ok)
            }

            DeviceCommand::SetCursorVisible(visible) => {
                self.set_cursor_visible(visible)?;
                Ok(DeviceResponse::Ok)
            }

            _ => Ok(DeviceResponse::Error("Not implemented".to_string())),
        }
    }

    fn shutdown(&mut self) -> Result<()> {
        // 清理 wake_lock_child
        self.stop_sleep_inhibit()?;

        // 清理 cursor_child
        if let Some(mut child) = self.cursor_child.take() {
            let _ = child.kill();
            let _ = child.wait();
        }

        // 确保清理所有 unclutter 进程
        let _ = Command::new("pkill")
            .args(["-f", "unclutter"])
            .stdin(Stdio::null())
            .stdout(Stdio::null())
            .stderr(Stdio::null())
            .status();

        Ok(())
    }
}
