#ifndef SLEEP_THREAD_HPP_
#define SLEEP_THREAD_HPP_

/*
*        跟 Sleep 的功能相同,其不同点是可以 随时终止正在进行的 Sleep。
*/

#include <thread>
#include <mutex>

namespace cpppub {

typedef class CThreadSleep
{
public:
    CThreadSleep();
    ~CThreadSleep() = default;
public:
    // 进入睡眠,不传入值使用默认值,传入则使用传入值。
    void Sleep(int nMilliseconds = 0);
    // 停止所有的 Sleep 睡眠,继续向下。
    void Contiune();
    // 设置默认的睡眠时长,不填写时其默认值为 10 ms, 如果传入 <= 0 值将使用默认的 10 ms。
    void SetTimeOut(int nMilliseconds);

private:
    bool getStatus() const;

private:
    // 同步原语,能用于阻塞一个线程,或同时阻塞多个线程,直至另一线程修改共享变量(条件)并通知 condition_variable
    std::condition_variable        m_Cv;
    int                            m_nTimeOut;                    // 睡眠时间
    const int                      m_nDefaultTimeOut = 10;        // 默认睡眠时间
    std::mutex                     m_Mutex;                       // 锁
    bool                           m_bStopSleep;                  // 睡眠标志位
}ThreadSleep;

CThreadSleep::CThreadSleep()
{
    m_bStopSleep = false;
    m_nTimeOut = 10;
}

inline void CThreadSleep::Sleep(int nMilliseconds)
{
    int nSleepTime = m_nTimeOut;
    if (nMilliseconds > 0)
        nSleepTime = nMilliseconds;

    m_bStopSleep = false;
    std::unique_lock<std::mutex>    lock(m_Mutex);
    std::chrono::system_clock::time_point nowtime = std::chrono::system_clock::now();

    // 度过 timeout 时限后 函数求值为 false 则为 false,否则为 true。
    // 若已度过时限,则求值并返回求值结果。
    if (m_Cv.wait_until(lock, nowtime + (std::chrono::milliseconds(nSleepTime)),
                        [this]  { return getStatus(); })) {
        // 这里触发手动关闭
    }
    else {
        // 这里触发超时
    }
}

inline void CThreadSleep::Contiune()
{
    m_bStopSleep = true;
    m_Cv.notify_all();
}

inline void CThreadSleep::SetTimeOut(int nMilliseconds)
{
    if (nMilliseconds <= 0)
        m_nTimeOut = m_nDefaultTimeOut;
    else
        m_nTimeOut = nMilliseconds;
}

inline bool CThreadSleep::getStatus() const
{
    return m_bStopSleep;
}

}
#endif // !SLEEP_THREAD_HPP_