#ifndef __VENDOR_VENDOR_BASE_H__
#define __VENDOR_VENDOR_BASE_H__
#include <condition_variable>
#include <cstdio>
#include <fstream>
#include <functional>
#include <getopt.h>
#include <iostream>
#include <memory>
#include <mutex>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <sys/stat.h>
#include <sys/time.h>
#include <thread>
#include <unistd.h>
#include <utils/logger.h>
#include <uv.h>
#include <vector>

#ifndef WIN32
#include <execinfo.h>
#endif

namespace vendor {

class VendorBase;
struct MyOpt {
    const char *name;
    int has_arg;
    int val;
    const char *desc;
};

struct LongOpts {
    const MyOpt *myOpt;
    int sizeOpt;

    LongOpts(const MyOpt opts[], const int size);

    void GetOptions(struct option *opts, std::string &shorts);

    MyOpt GetOption(char ch, int index);
};

class VendorIf {
public:
    virtual void OnEvent(void *args) = 0;
    virtual void OnTimer(void *args) = 0;
    virtual void OnShot(void *args) = 0;
};

class VendorBase {
public:
    VendorBase();
    virtual ~VendorBase();
    static int32_t ParseOptionArgs(VendorBase *vendor, int argc, char *argv[]);

    void ListenSignal(int signal);
    int Exec();
    void Exit(int signal);
    uv_handle_t *AppendEvent(int fd, int ev, VendorIf *vif);
    uv_handle_t *AppendTimerEvent(int millionsecs, VendorIf *vif);
    uv_handle_t *AppendTimerEvent(
        int millionsecs, std::function<void()> timerFunc);
    void StopEvent(uv_handle_t *handle);

protected:
    virtual int ParseCmdline(const std::string &optname, const std::string &optarg) = 0;
    virtual MyOpt *GetOpts() = 0;
    virtual int GetOptSize() = 0;
    virtual void Signal(int signal) {}

public:
    virtual int Run() = 0;
    virtual std::string Name() = 0;
    virtual void Stop(int signal) = 0;

    static void SignalHandler(uv_signal_t *handle, int signum);

private:
    uv_loop_t *uvLoop_;
    std::vector<uv_handle_t *> uvSignals_;
};

} // namespace vendor

#endif // __VENDOR_VENDOR_BASE_H__