#include "ParseBuffer.hpp"
#include "IrcParser.hpp"

ParseBuffer::ParseBuffer(void) : _maxLineSize(512)
{
}

ParseBuffer::ParseBuffer(size_t maxLineSize) : _maxLineSize(maxLineSize)
{
}

ParseBuffer::ParseBuffer(const ParseBuffer &other)
{
	*this = other;
}

ParseBuffer &ParseBuffer::operator=(const ParseBuffer &other)
{
	if (this != &other)
	{
		_buffer = other._buffer;
		_maxLineSize = other._maxLineSize;
	}
	return (*this);
}

ParseBuffer::~ParseBuffer(void)
{
}

void ParseBuffer::append(const char *data, size_t len)
{
	if (data && len > 0)
		_buffer.append(data, len);
}

/*
	Extract lines terminated by:
	- "\r\n" standard IRC
	- "\n" useful for netcat/manual tests

	The returned line does not include CRLF/LF.
*/
bool ParseBuffer::extractOneLine(std::string &line)
{
	size_t lf = _buffer.find('\n');

	if (lf == std::string::npos)
		return (false);

	line = _buffer.substr(0, lf);
	if (!line.empty() && line[line.size() - 1] == '\r')
		line.erase(line.size() - 1);

	_buffer.erase(0, lf + 1);
	return (true);
}

std::vector<IrcMessage> ParseBuffer::extractMessages(void)
{
	std::vector<IrcMessage>	messages;
	std::string				line;

	while (extractOneLine(line))
	{
		IrcMessage msg;

		if (line.size() + 2 > _maxLineSize)
		{
			msg.setRaw(line);
			msg.setError("line too long");
			msg.setValid(false);
		}
		else
			msg = IrcParser::parseLine(line);
		messages.push_back(msg);
	}
	return (messages);
}

void ParseBuffer::clear(void)
{
	_buffer.clear();
}

const std::string &ParseBuffer::raw(void) const
{
	return (_buffer);
}

size_t ParseBuffer::size(void) const
{
	return (_buffer.size());
}
