//! 中断控制器驱动`Trait`定义

use core::{fmt::Display, result};

use crate::smp::Cpumask;

/// 中断错误
#[derive(Debug)]
pub enum IrqError {
    /// 无效参数
    Invalid,
}

/// 中断结果
pub type Result<T> = result::Result<T, IrqError>;

impl Display for IrqError {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let error = match self {
            Self::Invalid => "Invalid args",
        };
        write!(f, "{error}")
    }
}

bitflags::bitflags! {
    /// 中断触发类型
    #[derive(Clone, Copy, Default)]
    pub struct IrqType: u32 {
        /// 无类型
        const IRQ_TYPE_NONE = 0;
        /// 上升沿触发
        const IRQ_TYPE_EDGE_RISING = 0x1;
        /// 下降沿触发
        const IRQ_TYPE_EDGE_FALLING = 0x2;
        /// 上升沿触发或者下降沿触发
        const IRQ_TYPE_EDGE_BOTH = IrqType::IRQ_TYPE_EDGE_RISING.bits()  | IrqType::IRQ_TYPE_EDGE_FALLING.bits() ;
        /// 高电平触发
        const IRQ_TYPE_LEVEL_HIGH = 0x4;
        /// 低电平触发
        const IRQ_TYPE_LEVEL_LOW = 0x8;
        /// 高低电平掩码
        const IRQ_TYPE_LEVEL_MASK = IrqType::IRQ_TYPE_LEVEL_HIGH.bits()  | IrqType::IRQ_TYPE_LEVEL_LOW.bits() ;
        /// 总掩码
        const IRQ_TYPE_MASK = IrqType::IRQ_TYPE_EDGE_BOTH.bits() | IrqType::IRQ_TYPE_LEVEL_MASK.bits();
    }
}

bitflags::bitflags! {
    /// 中断状态
    #[derive(Clone, Copy, Default, PartialEq, PartialOrd)]
    pub struct IrqState: u32 {
        /// 中断是 percpu
        const IRQ_PER_CPU = 1 << 0;
        /// 中断没有使用
        const IRQ_NOREQUEST = 1 << 1;

        /// 中断挂起(中断无处理)
        const IRQ_PENDING = 1 << 2;
        /// 中断正在处理
        const IRQ_INPROGRESS = 1 << 3;
        /// 中断未激活
        const IRQ_MASKED = 1 << 4;
    }
}

/// 中断控制器特定的状态
#[derive(Clone, Copy)]
#[allow(non_camel_case_types)]
pub enum IrqchipIrqState {
    /// 中断挂起?
    IRQCHIP_STATE_PENDING,
    /// 中断在处理?
    IRQCHIP_STATE_ACTIVE,
    /// 中断被禁用?
    IRQCHIP_STATE_MASKED,
    /// 中断信号高电平?
    IRQCHIP_STATE_LINE_LEVEL,
}

/// 中断控制器实现
#[allow(unused_variables)]
pub trait IrqchipImpl {
    /// 中断控制器名字
    fn name(&self) -> &'static str;

    /// 该中断控制器管理的中断数量
    fn irqs_max(&self) -> usize;

    /// 应答中断
    fn irq_ack(&self, hwirq: u32) {}
    /// 结束中断
    fn irq_eoi(&self, hwirq: u32);

    /// 禁用中断
    fn irq_disable(&self, hwirq: u32);
    /// 激活中断
    fn irq_enable(&self, hwirq: u32);

    /// 设置中断亲和性
    ///
    /// # Errors
    /// 中断号或者 cpumask 不正确会返回错误
    fn irq_set_affinity(&self, hwirq: u32, cpumask: Cpumask) -> Result<()>;
    /// 设置中断触发类型
    ///
    /// # Errors
    /// 中断号不正确会返回错误
    fn irq_set_type(&self, hwirq: u32, irq_type: IrqType) -> Result<()>;

    /// 获取中断控制器特定状态是否激活
    ///
    /// # Errors
    /// 中断号不正确会返回错误
    fn irq_get_irqchip_state(&self, hwirq: u32, which: IrqchipIrqState) -> Result<bool>;
    /// 设置中断控制器特定状态
    ///
    /// # Errors
    /// 中断号或者设置状态不正确会返回错误
    fn irq_set_irqchip_state(&self, hwirq: u32, which: IrqchipIrqState, state: bool) -> Result<()>;

    /// 向特定处理器发送 ipi 中断
    fn ipi_send_single(&self, hwirq: u32, cpu: usize) {
        let cpumask = Cpumask::new();
        cpumask.set(cpu);
        self.ipi_send_mask(hwirq, &cpumask);
    }
    /// 向一组处理器发送 ipi 中断
    fn ipi_send_mask(&self, hwirq: u32, cpumask: &Cpumask);

    /// 硬中断回调
    ///
    /// 对应架构处理器直接调用该回调
    fn irq_handler(&self);

    /// 中断控制器初始化
    fn irq_init(&self);
    /// 中断控制器处理器初始化
    ///
    /// 该回调将在每个处理器上调用初始化cpu接口
    fn irq_init_cpu(&self);
}
