#ifndef THREADPOOL_HPP
#define THREADPOOL_HPP

#include <atomic>
#include <condition_variable>
#include <functional>
#include <iostream>
#include <memory> //unique_ptr
#include <queue>
#include <stdexcept>
#include <thread>
#include <vector>

typedef std::function<void(void)> Task;

class ThreadPool {
public:
    /**
     * @brief ThreadPool
     * @param number[in]线程数 *默认开一个线程
     * @param
     * emptyQuit[in]空线程退出，默认false。如果为true，需要先添加任务，再start，然后waite完成
     */
    ThreadPool(int number = 1, bool emptyQuit = false);
    ~ThreadPool();

    /**
     * @brief append 往请求队列＜task_queue＞中添加任务<T *>
     * @param task
     * @return
     */
    bool append(Task task);
    /**
     * @brief start 启动
     */
    void start();
    /**
     * @brief stop 停止
     */
    void stop();
    /**
     * @brief waiteFinish 等待所有任务结束,设置为任务为空退出时调用
     */
    void waiteFinish();
    /**
    * @brief 任务数
    */
    int taskNum();
private:
    /**
     * @brief worker 线程回调函数
     * @param arg
     * @return
     */
    static void *worker(void *arg);
    /**
     * @brief run 工作线程需要运行的函数,不断的从任务队列中取出并执行
     */
    void run();
    /**
     * @brief stopThreadGroup 停止线程组
     */
    void stopThreadGroup();
    /**
     * @brief startThread 启动线程
     */
    void startThread();
    /**
     * @brief waiteThreadFinish 等待线程结束
     */
    void waiteThreadFinish();
    /**
     * @brief notEmpty 是否空
     * @return
     */
    bool notEmpty();

private:
    std::vector<std::thread *> m_WorkThreads; /*工作线程*/
    std::queue<Task> m_TasksQueue;            /*任务队列*/

    std::mutex m_QueueMutex;
    std::condition_variable m_Condition; /*必须与unique_lock配合使用*/

    std::recursive_mutex m_DataMutex; //数据锁

    std::atomic_bool m_StopFlag; //是否停止标志
    std::once_flag m_CallStopSlag;
    std::once_flag m_CallStartSlag;
    std::once_flag m_CallWaiteFinisFlag;
    int m_ThreadNum; //线程数

    std::atomic_bool m_EmptyQuit; //无任务退出模式,改模式先添加任务，再启动
    std::atomic_bool m_JoinFlag; //线程是否Join
 
    std::atomic_bool   m_EmptyQuitWaite;//开始退出等待
    std::atomic_int    m_QuitNum;//退出的线程计数

};
typedef std::shared_ptr<ThreadPool> ThreadPoolPtr;

#endif // THREADPOOL_HPP
