#include "TaskExecutor.h"

#include "Logger.h"


void TaskExecutor::Shutdown() {
    stop = true;
    for (auto &[command, future]: tasks) {
        if (future.valid()) {
            try {
                command->RequestStop();
                future.wait(); // Wait for the task to finish
                future.get(); // Then call get() to handle any exceptions
            } catch (const std::exception &e) {
                loge << "Exception during task shutdown: " << e.what() << std::endl;
            } catch (...) {
                loge << "Unknown exception during task shutdown" << std::endl;
            }
        }
    }
    tasks.clear();
}


void TaskExecutor::AddTask(std::shared_ptr<ExecutableTask> command) {
    std::lock_guard<std::mutex> lock(queueMutex);
    std::future<void> future = std::async(std::launch::async, [command]() {
        try {
            command->Execute();
        } catch (const std::exception &e) {
            loge << "Error executing command: " << e.what() << std::endl;
        }
    });
    tasks.push_back({command, std::move(future)});
}

bool TaskExecutor::IsTaskTypeRunning(TaskTypeEnum taskType) const {
    std::lock_guard lock(queueMutex);
    return std::ranges::any_of(tasks, [taskType](const Task &task) {
        return task.task->TaskType() == taskType;
    });
}


void TaskExecutor::RemoveFinishedTasks() {
    std::lock_guard<std::mutex> lock(queueMutex);
    std::erase_if(tasks, [](Task &task) {
        if (task.future.valid() && task.future.wait_for(std::chrono::seconds(0)) == std::future_status::ready) {
            // Handle exceptions
            try {
                task.future.get(); // This will rethrow the exception if any
            } catch (const std::exception &e) {
                loge << "Exception from finished task: " << e.what() << std::endl;
            } catch (...) {
                loge << "Unknown exception from finished task" << std::endl;
            }
            return true; // Remove task from the list
        }
        return false; // Keep the task in the list
    });
}


