#include "ComWatch.h"
#include <algorithm>
#include <chrono>
#include <ranges>
namespace ranges = std::ranges;
namespace views = std::ranges::views;
using namespace std::literals::chrono_literals;
SerialWatch::~SerialWatch() {
    s.request_stop();
    if (work_thread.joinable()) {
        work_thread.join();
    }
}

void SerialWatch::set_callback(
    std::function<void(const std::string&, SIGNAL_TYPE type)> func) {
    this->callback = func;
}

void SerialWatch::work() {
    this->work_thread = std::jthread(
        [this](std::stop_token token) {
            std::vector<std::string> pre_ports;
            while (!token.stop_requested()) {
                auto curr_ports = serial::GetUsbPorts();
                for (auto &&port : pre_ports) {
                    if (ranges::find(curr_ports, port) == curr_ports.end()) {
                        std::lock_guard<std::mutex> lock(m);
                        if (callback)
                            callback(port, SIGNAL_TYPE::REMOVE_);
                    }
                }
                for (auto &&port : curr_ports) {
                    if (ranges::find(pre_ports, port) == pre_ports.end()) {
                        std::lock_guard<std::mutex> lock(m);
                        if (callback)
                            callback(port, SIGNAL_TYPE::ADD_);
                    }
                }
                pre_ports = std::move(curr_ports);
                std::this_thread::sleep_for(500ms);
            }
        },
        s.get_token());
}