#ifndef INCLUDED_BOBCAT_SOCKETBASE_
#define INCLUDED_BOBCAT_SOCKETBASE_

#include <string>
#include <sys/socket.h>

#include <bobcat/inetaddress>
#include <bobcat/exception>

//    int info coming in/going out: host byte order

namespace FBB
{

class SocketBase: public InetAddress
{
    int         d_sock;

    public:
        bool debug() const;                                         // .f
        bool reuse() const;                                         // .f
        int socket() const;                                         // .f

        bool setDebug(bool trueIsOn);                               // .f
        bool setReuse(bool trueIsOn);                               // .f

    protected:
        explicit SocketBase(uint16_t port);                         // 1
        SocketBase(std::string const &host, uint16_t port);         // 2

        SocketBase(SocketBase const &other)          = default;
        SocketBase &operator=(SocketBase const &rhs) = default;

        SocketBase makeBase(int socket,                             // .f
                            sockaddr_in const &address);
    private:
        SocketBase(int socket, sockaddr_in const &address);         // 1.f

        bool boolOption(int optname) const;
        bool setBoolOption(int optname, bool newValue);
};

inline SocketBase::SocketBase(int socket, sockaddr_in const &address)
:
    InetAddress(address),
    d_sock(socket)
{}

inline bool SocketBase::debug() const
{
    return boolOption(SO_DEBUG);
}
inline bool SocketBase::reuse() const
{
    return boolOption(SO_REUSEADDR);
}
inline bool SocketBase::setDebug(bool trueIsOn)
{
    return setBoolOption(SO_DEBUG, trueIsOn);
}
inline bool SocketBase::setReuse(bool trueIsOn)
{
    return setBoolOption(SO_REUSEADDR, trueIsOn);
}
inline int SocketBase::socket() const
{
    return d_sock;
}
inline SocketBase SocketBase::makeBase(int socket, sockaddr_in const &address)
{
    return SocketBase{ socket, address };
}

} // FBB

#endif
