#![allow(dead_code)]

use system_error::SystemError;

use crate::{
    arch::ipc::signal::Signal,
    libs::{
        spinlock::SpinLock,
        wait_queue::{TimeoutWaker, WaitQueue, Waiter},
    },
    process::ProcessManager,
    time::timer::Timer,
};

const COMPLETE_ALL: u32 = u32::MAX;
const MAX_TIMEOUT: i64 = i64::MAX;

/// Signal response mode used while waiting on a completion.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum WaitMode {
    /// Uninterruptible sleep: ignores all signals.
    Uninterruptible,
    /// Interruptible by any pending signal.
    Interruptible,
    /// Interruptible only by fatal signals.
    Killable,
}

#[derive(Debug)]
pub struct Completion {
    inner: SpinLock<InnerCompletion>,
}

impl Completion {
    pub const fn new() -> Self {
        Self {
            inner: SpinLock::new(InnerCompletion::new()),
        }
    }

    /// @brief 基本函数：通用的处理wait命令的函数(即所有wait_for_completion函数最核心部分在这里)
    ///
    /// @param timeout jiffies
    /// @param mode the signal response mode of the sleep
    /// @return 返回剩余时间或者SystemError
    fn do_wait_for_common(&self, timeout: i64, mode: WaitMode) -> Result<i64, SystemError> {
        let pcb = ProcessManager::current_pcb();

        // None 代表无限等待；Some(jiffies) 代表还剩多少 jiffies
        let mut remaining = if timeout == MAX_TIMEOUT {
            None
        } else {
            Some(timeout)
        };

        loop {
            // 快路径：已完成直接消费
            {
                let mut inner = self.inner.lock_irqsave();
                if inner.done != 0 {
                    if inner.done != COMPLETE_ALL {
                        inner.done = inner.done.saturating_sub(1);
                    }
                    return Ok(match remaining {
                        Some(r) if r > 0 => r,
                        Some(_) => 1,
                        None => MAX_TIMEOUT,
                    });
                }
            }

            // Interruptible mode checks any pending signal; killable only fatal ones; uninterruptible ignores signals.
            let has_pending = match mode {
                WaitMode::Uninterruptible => false,
                WaitMode::Interruptible => pcb.sig_info_irqsave().sig_pending().has_pending(),
                WaitMode::Killable => Signal::signal_pending_state(false, true, &pcb),
            };
            if has_pending {
                return Err(SystemError::ERESTARTSYS);
            }

            if remaining.is_some_and(|r| r <= 0) {
                return Ok(0);
            }

            // 构造一次等待 + 可选超时定时器
            let (waiter, waker) = Waiter::new_pair();

            // 注册 waker，并在注册前后都检查 done 以避免丢唤醒
            {
                let mut inner = self.inner.lock_irqsave();
                if inner.done != 0 {
                    if inner.done != COMPLETE_ALL {
                        inner.done = inner.done.saturating_sub(1);
                    }
                    return Ok(match remaining {
                        Some(r) if r > 0 => r,
                        Some(_) => 1,
                        None => MAX_TIMEOUT,
                    });
                }
                inner.wait_queue.register_waker(waker.clone())?;
            }

            // 可选定时器
            let mut timer = None;
            if let Some(r) = remaining {
                let jiffies = r as u64;
                let t = Timer::new(TimeoutWaker::new(waker.clone()), jiffies);
                t.activate();
                timer = Some(t);
            }

            // 阻塞等待
            let wait_res = match mode {
                WaitMode::Uninterruptible => waiter.wait(false),
                WaitMode::Interruptible => waiter.wait(true),
                WaitMode::Killable => waiter.wait_killable(),
            };

            // 取消定时器（如果还没超时）
            if let Some(t) = &timer {
                if !t.timeout() {
                    t.cancel();
                }
            }

            // 从队列摘除自身（若还在）
            {
                let inner = self.inner.lock_irqsave();
                inner.wait_queue.remove_waker(&waiter.waker());
            }

            // 检查超时
            if let Some(t) = timer {
                if t.timeout() {
                    return Ok(0);
                }
                if let Some(rem) = remaining.as_mut() {
                    *rem = rem.saturating_sub(1);
                }
            }

            wait_res?;
        }
    }

    /// @brief 等待指定时间，超时后就返回, 同时设置pcb state为uninteruptible.
    /// @param timeout 非负整数，等待指定时间，超时后就返回/或者提前done
    pub fn wait_for_completion_timeout(&self, timeout: i64) -> Result<i64, SystemError> {
        self.do_wait_for_common(timeout, WaitMode::Uninterruptible)
    }

    /// @brief 等待completion命令唤醒进程, 同时设置pcb state 为uninteruptible.
    pub fn wait_for_completion(&self) -> Result<i64, SystemError> {
        self.do_wait_for_common(MAX_TIMEOUT, WaitMode::Uninterruptible)
    }

    /// @brief Wait for the completion to be done, but can be interrupted by any signal
    pub fn wait_for_completion_interruptible(&self) -> Result<i64, SystemError> {
        self.do_wait_for_common(MAX_TIMEOUT, WaitMode::Interruptible)
    }

    /// @brief Wait for the completion to be done, interruptible only by fatal signals.
    pub fn wait_for_completion_killable(&self) -> Result<i64, SystemError> {
        self.do_wait_for_common(MAX_TIMEOUT, WaitMode::Killable)
    }

    /// @brief Wait for the completion to be done, interruptible by any signal, with a timeout
    pub fn wait_for_completion_interruptible_timeout(
        &mut self,
        timeout: i64,
    ) -> Result<i64, SystemError> {
        assert!(timeout >= 0);
        self.do_wait_for_common(timeout, WaitMode::Interruptible)
    }

    /// @brief 唤醒一个wait_queue中的节点
    pub fn complete(&self) {
        let mut inner = self.inner.lock_irqsave();
        if inner.done != COMPLETE_ALL {
            inner.done = inner.done.saturating_add(1);
        }
        inner.wait_queue.wakeup(None);
        // 脱离生命周期，自动释放guard
    }

    /// @brief 永久标记done为Complete_All，并从wait_queue中删除所有节点
    pub fn complete_all(&self) {
        let mut inner = self.inner.lock_irqsave();
        inner.done = COMPLETE_ALL;
        inner.wait_queue.wakeup_all(None);
        // 脱离生命周期，自动释放guard
    }

    /// @brief @brief 尝试获取completion的一个done！如果您在wait之前加上这个函数作为判断，说不定会加快运行速度。
    ///
    /// @return true - 表示不需要wait_for_completion，并且已经获取到了一个completion(即返回true意味着done已经被 减1 )
    /// @return false - 表示当前done=0，您需要进入等待，即wait_for_completion
    pub fn try_wait_for_completion(&mut self) -> bool {
        let mut inner = self.inner.lock_irqsave();
        if inner.done == 0 {
            return false;
        }

        if inner.done != 0 {
            return false;
        } else if inner.done != COMPLETE_ALL {
            inner.done -= 1;
        }
        return true;
        // 脱离生命周期，自动释放guard
    }

    // @brief 测试一个completion是否有waiter。（即done是不是等于0）
    pub fn completion_done(&self) -> bool {
        let inner = self.inner.lock_irqsave();
        if inner.done == 0 {
            return false;
        }

        if inner.done == 0 {
            return false;
        }
        return true;
        // 脱离生命周期，自动释放guard
    }
}
#[derive(Debug)]
pub struct InnerCompletion {
    done: u32,
    wait_queue: WaitQueue,
}

impl InnerCompletion {
    pub const fn new() -> Self {
        Self {
            done: 0,
            wait_queue: WaitQueue::default(),
        }
    }
}
