
#include "Webserv.hpp"

// Arbitrary values
#define BUFSIZE 8192 // (8Ko)
#define MAX_HEADER_SIZE 16384 // (16Ko)

enum read_return
{
	READ_IN_PROGRESS,
	READ_COMPLETE,
	READ_CLOSE,
};

void	Webserv::_request(Client *client)
{
	int ret = _read_request(client);

	if (g_last_signal)
		_handle_last_signal();

	if (ret == READ_CLOSE)
	{
		_close_client(client->get_cl_fd());
	}
	else if (ret == READ_COMPLETE)
	{
		if (client->body_complete && client->get_rq_multi_bodys().empty()) // DEBUG
			std::cerr << "______BODY\n" << client->get_rq_body() << "\n______\n"; // DEBUG
		_epoll_update(client->get_cl_fd(), EPOLLOUT, EPOLL_CTL_MOD);
		client->request_complete = true;
	}
}

int	Webserv::_read_request(Client *client)
{
	char	buf[BUFSIZE];
	ssize_t	ret;

	ret = ::recv(client->get_cl_fd(), buf, BUFSIZE, 0);
	std::cerr << "recv() on fd(" << client->get_cl_fd() << ") returned = " << ret << "\n" ;
	if (ret == -1)
	{
		std::perror("err recv()");
		return READ_CLOSE;
	}
	if (ret == 0)
	{
		std::cerr << "recv() read 0, then close client" << "\n"; // DEBUG
		return READ_CLOSE;
	}
	client->raw_request.append(buf, ret);
	// ::print_special(client->raw_request);
	// std::cerr << "__raw_request__\n" << client->raw_request << "\n______\n"; // DEBUG

	print_special(client->raw_request);

	std::cerr << "client header complete: " << client->header_complete << "\n"; // DEBUG

	if (!client->header_complete)
	{
		std::cout << "Header not complete\n"; // debug
		client->parse_request_headers(_servers);
		if (client->status)
			return READ_COMPLETE;
		if (client->header_complete)
		{
			if (client->get_rq_headers("Content-Type").empty()
			&& client->get_rq_headers("Content-Length").empty()
			&& client->get_rq_headers("Transfer-Encoding").empty())
				return READ_COMPLETE; // No body case
		}
		else if (client->raw_request.size() > MAX_HEADER_SIZE)
		{ // 413 or 400 ? 413 seems common among http server, but don't fit perfectly.
			client->status = 413;
			return READ_COMPLETE;
		}
	}
	if (client->header_complete)
	{
		std::cerr << "Client header Complete\n";
		// client->read_body_size += ret; // Not accurate, part of body could have been read with headers, unused for now
		client->parse_request_body();
		if (client->status || client->body_complete)
			return READ_COMPLETE;
	}

	return READ_IN_PROGRESS;
}
