#include "thread_pool.h"

#include "logging.h"

namespace zsy
{
    ThreadPool::ThreadPool(std::string name, const uint16_t threadCount): name(name), status(0), threadCount(threadCount < 1 ? 1 : threadCount)
    {
        std::lock_guard lock(status_mtx);
        status = 1;
        createThread();
    }

    void ThreadPool::createThread()
    {
        for (size_t i = 0; i < threadCount; ++i)
        {
            LOGGER_INFO("创建线程：{}-{} 号", name, i);
            threads.emplace_back([this,i](const std::stop_token &st)
            {
                while (!st.stop_requested())
                {
                    std::function<void()> task;
                    {
                        std::unique_lock lock(queueMutex);
                        taskCondition.wait(lock, st, [this]
                        {
                            return !tasks.empty();
                        });

                        if (st.stop_requested() && tasks.empty())
                        {
                            LOGGER_INFO("线程已停止：{}-{} 号", name, i);
                            return;
                        }
                        task = std::move(tasks.front());
                        tasks.pop();
                    }
                    try
                    {
                        LOGGER_INFO("开始执行任务：{}-{} 号", name, i);
                        if (task) task();
                        LOGGER_INFO("任务执行完成：{}-{} 号", name, i);
                    } catch (const std::exception &e)
                    {
                        LOGGER_ERROR("任务执行失败：{}-{} 号， {}", name, i, e.what());
                    }
                    catch (...)
                    {
                        LOGGER_ERROR("未知异常，任务执行失败：{}-{} 号", name, i);
                    }
                }
            });
        }
    }

    void ThreadPool::submit(const std::function<void()> &task)
    {
        addTask(task);
        taskCondition.notify_one();
    }


    void ThreadPool::addTask(const std::function<void()> &task)
    {
        std::shared_lock status_lock(status_mtx);
        if (status != 1)
        {
            LOGGER_ERROR("线程池未启动");
            return;
        }
        std::unique_lock lock(queueMutex);
        tasks.emplace(task);
    }

    ThreadPool::~ThreadPool()
    {
        std::lock_guard lock(status_mtx);
        status = 2;
        LOGGER_INFO("正在销毁线程池：{}", name);
        threads.clear();
        LOGGER_INFO("线程池已销毁：{}", name);
    }
} // zsy
