/*
 * NVSocks5Srv.h
 *
 *  Created on: May 12, 2022
 *      Author: dengminhao
 */
#pragma once
#ifndef YCKSDWAN_YCKSDWAN_SOCKS5_SRV_H_
#define YCKSDWAN_YCKSDWAN_SOCKS5_SRV_H_

#ifdef SDK_SIMPLE_INCLUDE
#include "common.h"
#else
#include <YCKSdwan/common.h>
#endif
#include <cstdint>
#include <string>

namespace NeuVision {

#ifndef NV_DNS_RESOLVER_
class DnsResolver{
public:
    virtual ~DnsResolver() = default;
    //The returned buffer is hold by resolver. Use it immediately or copy it.
    virtual std::string resolve(const char* domainname) = 0;
};
#define NV_DNS_RESOLVER_
#endif

class DLL_DECL_SDWAN Socks5Svr{

public:
    //port: listen port, can be 0.
    //verboseLevel: 0: open/close/error;  1: state change; 2: in/out bytes.
    Socks5Svr(int port,int bufferSize = 8196,int verboseLevel = 0);
    //if construct by port0, get real bind port.
    int realPort() const;
    //will not return util srv stopped.
    void start();
    void setVerboseLevel(int v);
    bool isAlive() const;
    //cannot start again for now. Using new instance.
    void tryStop();
    //cannot start again for now. Using new instance.
    void forceStop();
    //set a custom resolver, return previous one. The resolver lifecycle must be controlled outside Socks5Srv.
    DnsResolver* setCustomDnsResolver(DnsResolver* r);
    //Using the custom resolver SDK httpAPI used. This will call setCustomDnsResolver internally.
    DnsResolver* setDefaultCustomDnsResolver();
    DnsResolver* getDefaultCustomDnsResolver();
    ~Socks5Svr();
protected:
    void * impl;
};

}

#endif//YCKSDWAN_YCKSDWAN_SOCKS5_SRV_H_