
#ifndef CLIENT_HPP
# define CLIENT_HPP

# include <iostream>
# include <string>
# include <map>
# include <vector>
# include <string.h>		// strdup
# include "utils.hpp"
# include <netinet/in.h>	// sockaddr_in, struct in_addr
# include <arpa/inet.h>		// htonl, htons, ntohl, ntohs, inet_addr, inet_ntoa

struct Script
{
	std::string							path;
	std::string							info;
};

struct Request
{
	http_method							method;
	std::string							uri;
	std::string							abs_path;
	std::string							query;
	std::string							version;
	std::map<std::string, std::string>	headers;
	std::string							body;
	std::string							port;
	std::string							hostname;
	struct Script						script;
};

# define MAX_FILESIZE 1000000 // (1Mo)
class Client
{
	public:
		Client();
		Client(int afd, listen_socket *lsocket, std::string aport, std::string aip);
		~Client();
		Client(Client const &src);
		Client &operator=(Client const &rhs);

		std::string		raw_request;
		std::string		response;
		static char		buf[MAX_FILESIZE+1];
		size_t			body_size;
		unsigned int	status;

		// getters
		int						get_cl_fd() const;
		const std::string	&	get_cl_port() const;
		const std::string	&	get_cl_ip() const;
		const listen_socket *	get_cl_lsocket() const;

		// requests getters
		http_method		get_rq_method() const;
		std::string		get_rq_method_str() const;
		std::string		get_rq_uri() const;
		std::string		get_rq_abs_path() const;
		std::string		get_rq_query() const;
		std::string		get_rq_version() const;
		std::string		get_rq_body() const;
		std::string		get_rq_port() const;
		std::string		get_rq_hostname() const;
		std::string		get_rq_script_path() const;
		std::string		get_rq_script_info() const;
		std::string		get_rq_headers(const std::string & key) const;

		void	parse_request();
		void	clear();
		void	clear_request();
		void	clear_script();
		bool	fill_script_path(std::string script);

	private:
		const int				_fd;
		const std::string		_port;
		const std::string		_ip;
		const listen_socket *	_lsocket;
		struct Request			_request;

		void	_parse_request_line( std::string rline );
		void	_parse_request_uri( std::string uri );
		void	_parse_request_headers( std::vector<std::string> list );
		void	_parse_request_body( size_t pos );
		void	_parse_port_hostname(std::string host);

};

bool	operator==(const Client& lhs, const Client& rhs);
bool	operator==(const Client& lhs, int fd);
bool	operator==(int fd, const Client& rhs);

#endif

