#include <VWeb.h>
#include <thread>

namespace VWeb {
ThreadPool::ThreadPool(const std::string &name) : m_Name(name) {}
void ThreadPool::Create() {
  if (m_IsCreated)
    return;
  m_IsDone = false;
  m_IsCreated = true;
  m_Queue.Open();
  for (int i = 0; i < m_ThreadCount; ++i) {
    m_Threads.push_back(std::thread(&ThreadPool::Execute, this));
  };
  printf("[ThreadPool] >> Created %d Threads for Pool \"%s\"\n", m_ThreadCount, m_Name.c_str());
}
void ThreadPool::Stop() {
  m_IsDone = true;
  m_Queue.Flush();
  for (int i = 0; i < m_ThreadCount; ++i)
    m_Threads[i].join();
}
void ThreadPool::Dispatch(const Ref<WorkerJob> &job) { m_Queue.Push(job); }
void ThreadPool::SetThreadCount(int count) {
  if (m_IsCreated)
    return;
  m_ThreadCount =
      count == -1 ? (int)std::thread::hardware_concurrency() : count;
}

void ThreadPool::Execute() {
  if (!m_IsCreated)
    return;
  while (auto queueItem = m_Queue.WaitAndPop()) {
    if (!queueItem.has_value() || m_Queue.IsClosed())
      continue;
    auto &item = queueItem.value();
    if (item == nullptr)
      continue;
    item->Execute();
  }
}
} // namespace VWeb