#ifndef SERIAL_OPERATE
#define SERIAL_OPERATE

#if defined(DYNAMIC_DLL)
#if defined(_MSC_VER)
#define CPP_SERIALOPR_EXPORT __declspec(dllexport)
#define CPP_SERIALOPR_IMPORT __declspec(dllimport)
#else
#define CPP_SERIALOPR_EXPORT __attribute__((visibility("default")))
#define CPP_SERIALOPR_IMPORT __attribute__((visibility("default")))
#endif

#ifdef SERIALOPR_LIB
#define SERIALOPR_API CPP_SERIALOPR_EXPORT
#else
#define SERIALOPR_API CPP_SERIALOPR_IMPORT
#endif
#else
#define SERIALOPR_API
#endif

#include <cstdint>

namespace cppbox {

enum DataBits { D5 = 5, D6 = 6, D7 = 7, D8 = 8, UnKnowBits = -1 };

enum StopBits { OneStop = 1, OneAndHalfStop = 3, TwoStop = 2, UnknownStopBits = -1 };

enum Parity {
    NoParity = 0,
    EvenParity = 2,
    OddParity = 1
};

enum FlowControl { NoFlowControl, HardwareControl, SoftwareControl, UnknownFlowControl = -1 };

class CSerialOprImp;
class SERIALOPR_API CSerialOpr
{
public:
    CSerialOpr();
    ~CSerialOpr();

public:
    void set_port(const char* port);
    void set_baudrate(uint32_t baudrate);
    void set_data_bits(DataBits data_bits);
    void set_stop_bits(StopBits stop_bits);
    void set_parity(Parity parity);
    void set_flow_control(FlowControl flow_control);
    void set_timeout(uint64_t timeout);

public:
    int  open();
    void close();
    int  read(char* data);
    int  write(const char* data, int len);
    const char* get_last_error() const;

private:
    CSerialOprImp* imp_{};
};

}   // namespace cppbox

#endif