#include "serial.h"
#ifndef COMKIT_H

#include <optional>
#include <string>
#include <vector>
#include <ranges>
#include <mutex>

namespace ranges = std::ranges;
namespace views = std::ranges::views;

struct ComStruct {
    std::string comPortName;
    std::string comPortInstancePath;
};

template <typename T>
    requires std::is_same_v<T, std::string> ||
             std::is_same_v<T, std::string_view>
static std::vector<T> Split(T str, T d) {
    auto v = views::split(str, d) 
    | views::transform([](auto c){return T(c.begin(), c.end());})
    | views::filter([](auto word){return word != "";});
    return std::vector<T>(v.begin(), v.end());
}

class ComKit {
  public:
    static bool isWorking;
    static serial::Serial device;
    static std::ostringstream oss;
    static std::vector<ComStruct> *comPortNames;
    static std::optional<std::string>
    GetComPortInstancePath(const std::string &comPortName);
    static std::optional<std::string>
    GetUsbLocationPath(const std::string &comPortName);
    static std::vector<ComStruct> *GetAllComPortNames();
    static void Start(std::string, std::string);
    static void End();
    static void Work(const std::string& port_name);
    static bool ChangeComPortNumber(const std::string &oldPortName,
                                    const std::string &newPortName);
    static std::vector<std::string> watchingComPort;
    static std::vector<std::string> commands;
    static std::string logContent;
    static void FlushLog();
    static std::mutex m;
    static std::vector<std::string> Split(std::string str);

};

#endif