#ifndef _ACCEPTOR_H
#define _ACCEPTOR_H

#include <netinet/in.h>

#include <string>

#include "thread.h"

enum SocketType {
	TCP_SOCKET,
	UDP_SOCKET,
};
int create_server_socket(const sockaddr_in6 &addr, SocketType socket_type);

class AcceptorProto;

sockaddr_in6 create_any_address(int port);
sockaddr_in6 extract_address_from_acceptor_proto(const AcceptorProto &proto);

// A thread that accepts new connections on a given socket,
// and hands them off to the server pool.
class Acceptor : public Thread {
public:
	Acceptor(int server_sock, const sockaddr_in6 &addr,
	         const std::string &certificate_chain, const std::string &private_key);

	// Serialization/deserialization.
	Acceptor(const AcceptorProto &serialized);
	AcceptorProto serialize() const;

	bool is_tls() const { return !certificate_chain.empty(); }

	std::string get_certificate_chain() const {
		assert(is_tls());
		return certificate_chain;
	}

	std::string get_private_key() const {
		assert(is_tls());
		return private_key;
	}

	void close_socket();

private:
	virtual void do_work();

	int server_sock;
	sockaddr_in6 addr;
	std::string certificate_chain, private_key;  // Both empty for no TLS.
};

#endif  // !defined(_ACCEPTOR_H)
