#include "Win32WebRequest.h"

#include "StringUtils.h"
#include "HttpRequest.h"
#include "FileLogger.h"

#include "Win32TempFile.h"
#include "UnicodeUtils.h"

Win32WebRequest::Win32WebRequest()
	: mBuffer(DEFAULT_BUFFER_SIZE)
{
	mIsValid = mBuffer.isValid();
	mHandle = reinterpret_cast<PHTTP_REQUEST>(mBuffer.getBuffer());
}

bool Win32WebRequest::isValid() const
{
	return mIsValid;
}

void Win32WebRequest::zeroBufferMemory()
{
	::RtlZeroMemory(mHandle, mWorkingBufferSize);
}

PHTTP_REQUEST Win32WebRequest::getHandle() const
{
	return mHandle;
}

unsigned Win32WebRequest::getBufferSize() const
{
	return mWorkingBufferSize;
}

void Win32WebRequest::resizeBuffer(unsigned size)
{
	mWorkingBufferSize = size;
	mBuffer.reset(mWorkingBufferSize);
	if (!mBuffer.isValid())
	{
		mIsValid = false;
		return;
	}
	mHandle = reinterpret_cast<PHTTP_REQUEST>(mBuffer.getBuffer());
}

std::string Win32WebRequest::getUrlFromRequest() const
{
	return UnicodeUtils::utf16ToUtf8String(mHandle->CookedUrl.pAbsPath);
}

HttpRequest Win32WebRequest::getRequest() const
{
	HttpRequest::Verb verb;
	switch (mHandle->Verb)
	{
	case HttpVerbGET:
		verb = HttpRequest::Verb::GET;
		break;
	case HttpVerbPOST:
		verb = HttpRequest::Verb::POST;
		break;
	default:
		verb = HttpRequest::Verb::UNKNOWN;
		break;
	}

	HttpRequest request(verb, getUrlFromRequest());
	return request;
}

bool Win32WebRequest::startReceiveEntity()
{
	mEntityBuffer = std::make_unique<Win32Buffer>(ENTITY_BUFFER_SIZE);
	if (!mEntityBuffer->isValid())
	{
		MLOG_ERROR("Failed to allocate entity buffer");
		return false;
	}

	mTempFile = std::make_unique<Win32TempFile>();
	if (!mTempFile->isValid())
	{
		MLOG_ERROR("Failed to create tempfile");
		return false;
	}
	return true;
}

Win32Buffer* Win32WebRequest::getEntityBuffer() const
{
	return mEntityBuffer.get();
}

unsigned Win32WebRequest::getEntityBufferSize() const
{
	return ENTITY_BUFFER_SIZE;
}

Win32TempFile* Win32WebRequest::getTempFile() const
{
	return mTempFile.get();
}

void Win32WebRequest::flushEntityBuffer(unsigned numBytes)
{
	mEntityTotalSize += numBytes;
	mTempFile->write(mEntityBuffer->getBufferAsUChar(), numBytes);
}

unsigned Win32WebRequest::getEntityTotalSize() const
{
	return mEntityTotalSize;
}