/*******************************************************************************
 * Copyright (c) 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/


#include "stdafx.h"
#include "CrossfireServer.h"

/* initialize statics */
const wchar_t* CrossfireServer::CONTEXTID_PREAMBLE = L"xfIE::";
const wchar_t* CrossfireServer::HANDSHAKE = L"CrossfireHandshake\r\n";
const wchar_t* CrossfireServer::HEADER_CONTENTLENGTH = L"Content-Length:";
const wchar_t* CrossfireServer::LINEBREAK = L"\r\n";
const size_t CrossfireServer::LINEBREAK_LENGTH = 2;

const wchar_t* CrossfireServer::COMMAND_CHANGEBREAKPOINT = L"changebreakpoint";
const wchar_t* CrossfireServer::COMMAND_CLEARBREAKPOINT = L"clearbreakpoint";
const wchar_t* CrossfireServer::COMMAND_GETBREAKPOINT = L"getbreakpoint";
const wchar_t* CrossfireServer::COMMAND_GETBREAKPOINTS = L"getbreakpoints";
const wchar_t* CrossfireServer::COMMAND_SETBREAKPOINT = L"setbreakpoint";

/* command: listContexts */
const wchar_t* CrossfireServer::COMMAND_LISTCONTEXTS = L"listcontexts";
const wchar_t* CrossfireServer::KEY_CONTEXTS = L"contexts";
const wchar_t* CrossfireServer::KEY_CURRENT = L"current";

/* command: version */
const wchar_t* CrossfireServer::COMMAND_VERSION = L"version";
const wchar_t* CrossfireServer::KEY_VERSION = L"version";
const wchar_t* CrossfireServer::VERSION_STRING = L"0.3";

/* event: closed */
const wchar_t* CrossfireServer::EVENT_CLOSED = L"closed";

/* event: onContextChanged */
const wchar_t* CrossfireServer::EVENT_CONTEXTCHANGED = L"onContextChanged";
const wchar_t* CrossfireServer::KEY_NEWHREF = L"new-href";

/* event: onContextCreated */
const wchar_t* CrossfireServer::EVENT_CONTEXTCREATED = L"onContextCreated";

/* event: onContextDestroyed */
const wchar_t* CrossfireServer::EVENT_CONTEXTDESTROYED = L"onContextDestroyed";

/* event: onContextLoaded */
const wchar_t* CrossfireServer::EVENT_CONTEXTLOADED = L"onContextLoaded";

/* shared */
const wchar_t* CrossfireServer::KEY_HREF = L"href";


CrossfireServer::CrossfireServer() {
	m_bpManager = new CrossfireBPManager();
	m_connection = NULL;
	m_contexts = new std::map<DWORD, CrossfireContext*>;
	m_currentContext = NULL;
	m_handshakeReceived = false;
	m_inProgressPacket = new std::wstring;
	m_lastRequestSeq = -1;
	m_pendingEvents = new std::vector<CrossfireEvent*>;
	m_port = -1;
	m_processingRequest = false;
	m_processor = new CrossfireProcessor();
	m_windowHandle = 0;
}

CrossfireServer::~CrossfireServer() {
	delete m_bpManager;

	std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin();
	while (iterator != m_contexts->end()) {
		delete iterator->second;
		iterator++;
	}
	delete m_contexts;

	std::vector<CrossfireEvent*>::iterator iterator2 = m_pendingEvents->begin();
	while (iterator2 != m_pendingEvents->end()) {
		if (m_connection) {
			sendEvent(*iterator2);
		}
		delete *iterator2;
		iterator2++;
	}
	delete m_pendingEvents;

	delete m_inProgressPacket;
	delete m_processor;
	if (m_connection) {
		delete m_connection;
	}

	if (m_windowHandle) {
		CComPtr<ICrossfireServerClass> serverClass = NULL;
		HRESULT hr = CoGetClassObject(CLSID_CrossfireServer, CLSCTX_ALL, 0, IID_ICrossfireServerClass, (LPVOID*)&serverClass);
		if (FAILED(hr)) {
			Logger::error("~CrossfireServer: CoGetClassObject() failed", hr);
			return;
		}
		hr = serverClass->RemoveServer(m_windowHandle);
		if (FAILED(hr)) {
			Logger::error("~CrossfireServer: RemoveServer() failed", hr);
			return;
		}
	}
}

HRESULT STDMETHODCALLTYPE CrossfireServer::contextCreated(DWORD threadId, OLECHAR* href) {
	if (m_port == -1) {
		return S_FALSE;
	}

	HRESULT hr = registerContext(threadId, href);
	if (SUCCEEDED(hr)) {
		std::map<DWORD, CrossfireContext*>::iterator iterator = m_contexts->find(threadId);
		CrossfireContext* context = iterator->second;
		eventContextCreated(context);
	}
	return hr;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::contextDestroyed(DWORD threadId) {
	if (m_port == -1) {
		return S_FALSE;
	}

	std::map<DWORD, CrossfireContext*>::iterator iterator = m_contexts->find(threadId);
	if (iterator == m_contexts->end()) {
		Logger::error("CrossfireServer.contextDestroyed(): unknown context", threadId);
		return S_FALSE;
	}
	CrossfireContext* context = iterator->second;
	eventContextDestroyed(context);
	m_contexts->erase(iterator);
	delete context;
	return S_OK;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::contextLoaded(DWORD threadId) {
	if (m_port == -1) {
		return S_FALSE;
	}

	std::map<DWORD, CrossfireContext*>::iterator iterator = m_contexts->find(threadId);
	if (iterator == m_contexts->end()) {
		Logger::error("CrossfireServer.contextLoaded(): unknown context", threadId);
		return S_FALSE;
	}
	CrossfireContext* context = iterator->second;
	eventContextLoaded(context);
	return S_OK;
}

void CrossfireServer::disconnected() {
	reset();
}

CrossfireBPManager* CrossfireServer::getBreakpointManager() {
	return m_bpManager;
}

CrossfireContext* CrossfireServer::getRequestContext(CrossfireRequest* request) {
	std::wstring* contextId = request->getContextId();
	if (!contextId) {
		return NULL;
	}

	wchar_t* searchString = (wchar_t*)contextId->c_str();
	std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin();
	while (iterator != m_contexts->end()) {
		if (wcscmp(iterator->second->getName(), searchString) == 0) {
			return iterator->second;
		}
		iterator++;
	}
	return NULL;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::isActive(boolean* value) {
	*value = m_port != -1;
	return S_OK;
}

bool CrossfireServer::performRequest(CrossfireRequest* request) {
	wchar_t* command = request->getName();
	Value* arguments = request->getArguments();
	Value* responseBody = NULL;
	bool success = false;
	if (wcscmp(command, COMMAND_VERSION) == 0) {
		success = commandVersion(arguments, &responseBody);
	} else if (wcscmp(command, COMMAND_CHANGEBREAKPOINT) == 0) {
		CrossfireContext* context = getRequestContext(request);
		IBreakpointTarget* target = context ? (IBreakpointTarget*)context : (IBreakpointTarget*)m_bpManager;
		success = m_bpManager->commandChangeBreakpoint(arguments, target, &responseBody);
	} else if (wcscmp(command, COMMAND_CLEARBREAKPOINT) == 0) {
		CrossfireContext* context = getRequestContext(request);
		IBreakpointTarget* target = context ? (IBreakpointTarget*)context : (IBreakpointTarget*)m_bpManager;
		success = m_bpManager->commandClearBreakpoint(arguments, target, &responseBody);
	} else if (wcscmp(command, COMMAND_LISTCONTEXTS) == 0) {
		success = commandListContexts(arguments, &responseBody);
	} else if (wcscmp(command, COMMAND_GETBREAKPOINT) == 0) {
		CrossfireContext* context = getRequestContext(request);
		IBreakpointTarget* target = context ? (IBreakpointTarget*)context : (IBreakpointTarget*)m_bpManager;
		success = m_bpManager->commandGetBreakpoint(arguments, target, &responseBody);
	} else if (wcscmp(command, COMMAND_GETBREAKPOINTS) == 0) {
		CrossfireContext* context = getRequestContext(request);
		IBreakpointTarget* target = context ? (IBreakpointTarget*)context : (IBreakpointTarget*)m_bpManager;
		success = m_bpManager->commandGetBreakpoints(arguments, target, &responseBody);
	} else if (wcscmp(command, COMMAND_SETBREAKPOINT) == 0) {
		CrossfireContext* context = getRequestContext(request);
		IBreakpointTarget* target = context ? (IBreakpointTarget*)context : (IBreakpointTarget*)m_bpManager;
		success = m_bpManager->commandSetBreakpoint(arguments, target, &responseBody);
	} else {
		return false;	/* command not handled */
	}

	CrossfireResponse response;
	response.setName(command);
	response.setRequestSeq(request->getSeq());
	response.setRunning(true);
	response.setSuccess(success);
	if (success) {
		response.setBody(responseBody);
	} else {
		Value emptyBody;
		emptyBody.setType(TYPE_OBJECT);
		response.setBody(&emptyBody);
	}
	if (responseBody) {
		delete responseBody;
	}
	sendResponse(&response);
	return true;
}

void CrossfireServer::received(wchar_t* msg) {
	if (!m_handshakeReceived) {
		if (wcscmp(msg, HANDSHAKE) == 0) {
			m_handshakeReceived = true;
			m_connection->send(HANDSHAKE);
		} else {
			Logger::error("Crossfire content received before handshake, not processing it");
		}
		return;
	}

	m_inProgressPacket->append(std::wstring(msg));
	std::wstring packet;
	do {
		packet.clear();
		if (m_inProgressPacket->find(HEADER_CONTENTLENGTH) != 0) {
			Logger::error("request packet does not start with 'Content-Length:', not processing it");
			Logger::log(m_inProgressPacket);
			m_inProgressPacket->clear();
			break;
		}

		size_t endIndex = m_inProgressPacket->find(wchar_t('\r'));
		if (endIndex == std::wstring::npos) {
			Logger::error("request packet does not contain '\r', not processing it");
			Logger::log(m_inProgressPacket);
			m_inProgressPacket->clear();
			break;
		}

		size_t headerLength = wcslen(HEADER_CONTENTLENGTH);
		std::wstring lengthString = m_inProgressPacket->substr(headerLength, endIndex - headerLength);
		int lengthValue = _wtoi(lengthString.c_str());
		if (!lengthValue) {
			Logger::error("request packet does not have a valid 'Content-Length' value, not processing it");
			Logger::log(m_inProgressPacket);
			m_inProgressPacket->clear();
			break;
		}

		if (m_inProgressPacket->find(L"\r\n", endIndex) != endIndex) {
			Logger::error("request packet does not follow initial '\\r' with '\\n', not processing it");
			Logger::log(m_inProgressPacket);
			m_inProgressPacket->clear();
			break;
		}

		// TODO for now just skip over "tool:" lines, though these should really be validated

		size_t toolEnd = m_inProgressPacket->find(L"\r\n\r\n", endIndex);
		if (toolEnd == std::wstring::npos) {
			Logger::error("request packet does not contain '\\r\\n\\r\\n' to delimit its header, not processing it");
			Logger::log(m_inProgressPacket);
			m_inProgressPacket->clear();
			break;
		}
		size_t toolsLength = toolEnd - endIndex;
		size_t targetLength = wcslen(HEADER_CONTENTLENGTH) + lengthString.length() + 3 * LINEBREAK_LENGTH + toolsLength + lengthValue;

		if (targetLength <= m_inProgressPacket->length()) {
			packet.assign(m_inProgressPacket->substr(0, targetLength));
			m_inProgressPacket->erase(0, targetLength);
		}

		if (packet.length()) {
			CrossfireRequest* request = NULL;
			if (!m_processor->parseRequestPacket(&packet, &request)) {
				Logger::error("invalid request packet received, not processing it");
				Logger::log(&packet);
			} else {
				unsigned int seq = request->getSeq();
				if (seq <= m_lastRequestSeq) {
					// TODO handle out-of-order packets
					Logger::log("packet received out of sequence, still processing it");
				}
				m_lastRequestSeq = seq;
				m_processingRequest = true;
				if (!performRequest(request)) {
					/*
					 * the request's command was not handled by the server,
					 * so try to delegate to the specified context, if any
					 */
					CrossfireContext* context = getRequestContext(request);
					if (!context) {
						Logger::error("request command was unknown to the server and a valid context id was not provided, not processing it");
						Logger::log(&packet);
					} else {
						if (!context->performRequest(request)) {
							Logger::error("request command was unknown to the server and to the specified context, not processing it");
							Logger::log(&packet);
						}
					}
				}
				m_processingRequest = false;
				delete request;

				/*
				 * Debugger events may have been received in response to the request that was
				 * just processed.  These events can be sent now that processing of the request
				 * is complete.
				 */
				if (m_pendingEvents->size() > 0) {
// GWG HACK! helps JSDT with stepping
Logger::error("start sleep");
Sleep(500);
Logger::error("end sleep");

					std::vector<CrossfireEvent*>::iterator iterator = m_pendingEvents->begin();
					while (iterator != m_pendingEvents->end()) {
						sendEvent(*iterator);
						delete *iterator;
						iterator++;
					}
					m_pendingEvents->clear();
				}
			}
		}
	} while (packet.length() > 0 && m_inProgressPacket->length() > 0);
}

HRESULT STDMETHODCALLTYPE CrossfireServer::registerContext(DWORD threadId, OLECHAR* href) {
	if (m_port == -1) {
		return S_FALSE;
	}

	static int s_contextCounter = 0;

	CrossfireContext* context = NULL;
	std::map<DWORD, CrossfireContext*>::iterator iterator = m_contexts->find(threadId);
	if (iterator == m_contexts->end()) {
		context = new CrossfireContext(threadId, this);
		m_contexts->insert(std::pair<DWORD,CrossfireContext*>(threadId, context));
	} else {
		Logger::error("CrossfireServer.registerContext(): a context already exists for thread", threadId);
		return S_FALSE;
	}

	std::wstringstream stream;
	stream << CONTEXTID_PREAMBLE;
	stream << threadId;
	stream << "-";
	stream << s_contextCounter++;
	context->setName((wchar_t*)stream.str().c_str());
	context->setHref(href);
	return S_OK;
}

void CrossfireServer::reset() {
	m_connection->close();
	delete m_connection;
	m_connection = NULL;

	std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin();
	while (iterator != m_contexts->end()) {
		delete iterator->second;
		iterator++;
	}
	m_contexts->clear();
	m_currentContext = NULL;
	m_handshakeReceived = false;
	m_inProgressPacket->clear();
	m_lastRequestSeq = -1;
	m_port = -1;
}

void CrossfireServer::sendEvent(CrossfireEvent* eventObj) {
	/*
	 * If a request is being processed then events to be sent to
	 * the client should be queued and sent after the response to
	 * the request has been sent first.
	 */
	if (m_processingRequest) {
		CrossfireEvent* copy = NULL;
		eventObj->clone((CrossfirePacket**)&copy);
		m_pendingEvents->push_back(copy);
		return;
	}

	std::wstring* string = NULL;
	if (!m_processor->createEventPacket(eventObj, &string)) {
		Logger::error("CrossfireServer.sendEvent(): Invalid event packet, not sending it");
		return;
	}

	m_connection->send(string->c_str());
	delete string;
}

void CrossfireServer::sendResponse(CrossfireResponse* response) {
	std::wstring* string = NULL;
	if (!m_processor->createResponsePacket(response, &string)) {
		Logger::error("CrossfireServer.sendResponse(): Invalid response packet, not sending it");
		return;
	}
	m_connection->send(string->c_str());
	delete string;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::setCurrentContext(DWORD threadId) {
	if (m_port == -1) {
		return S_FALSE;
	}

	std::map<DWORD, CrossfireContext*>::iterator iterator = m_contexts->find(threadId);
	if (iterator == m_contexts->end()) {
		Logger::error("CrossfireServer.setCurrentContext(): unknown context", threadId);
		return S_FALSE;
	}
	CrossfireContext* context = iterator->second;
	CrossfireContext* oldContext = m_currentContext;
	m_currentContext = context;
	eventContextChanged(context, oldContext);
	return S_OK;
}

void CrossfireServer::setWindowHandle(unsigned long value) {
	m_windowHandle = value;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::start(unsigned int port) {
	if (m_port != -1) {
		return S_FALSE;
	}

	m_connection = new WindowsSocketConnection(this);
	if (!m_connection->init(port)) {
		delete m_connection;
		return S_FALSE;
	}
	m_port = port;
	m_connection->acceptConnection();
	return S_OK;
}

HRESULT STDMETHODCALLTYPE CrossfireServer::stop() {
	if (m_port == -1) {
		return S_FALSE;
	}

	eventClosed();
	reset();
	return S_OK;
}

/* commands */

bool CrossfireServer::commandListContexts(Value* arguments, Value** _responseBody) {
	Value contexts;
	contexts.setType(TYPE_ARRAY);
	std::map<DWORD,CrossfireContext*>::iterator iterator = m_contexts->begin();
	while (iterator != m_contexts->end()) {
		CrossfireContext* context = iterator->second;
		Value value_context;
		value_context.addObjectValue(/*KEY_CONTEXTID*/L"context_id", &Value(context->getName()));
		value_context.addObjectValue(KEY_HREF, &Value(context->getHref()));
		value_context.addObjectValue(KEY_CURRENT, &Value((bool)(context == m_currentContext)));
		contexts.addArrayValue(&value_context);
		iterator++;
	}

	Value* result = new Value();
	result->addObjectValue(KEY_CONTEXTS, &contexts);
	*_responseBody = result;
	return true;
}

bool CrossfireServer::commandVersion(Value* arguments, Value** _responseBody) {
	Value* result = new Value();
	result->addObjectValue(KEY_VERSION, &Value(VERSION_STRING));
	*_responseBody = result;
	return true;
}

/* events */

void CrossfireServer::eventClosed() {
	CrossfireEvent eventObj;
	eventObj.setName(EVENT_CLOSED);
	sendEvent(&eventObj);
}

void CrossfireServer::eventContextChanged(CrossfireContext* newContext, CrossfireContext* oldContext) {
	CrossfireEvent eventObj;
	eventObj.setName(EVENT_CONTEXTCHANGED);
	eventObj.setContextId(&std::wstring(newContext->getName()));
	Value data;
	data.addObjectValue(KEY_NEWHREF, &Value(&std::wstring(newContext->getHref())));
	if (oldContext) {
		data.addObjectValue(KEY_HREF, &Value(&std::wstring(oldContext->getHref())));
	}
	eventObj.setData(&data);
	sendEvent(&eventObj);
}

void CrossfireServer::eventContextCreated(CrossfireContext* context) {
	CrossfireEvent eventObj;
	eventObj.setName(EVENT_CONTEXTCREATED);
	eventObj.setContextId(&std::wstring(context->getName()));
	Value data;
	data.addObjectValue(KEY_HREF, &Value(&std::wstring(context->getHref())));
	eventObj.setData(&data);
	sendEvent(&eventObj);
}

void CrossfireServer::eventContextDestroyed(CrossfireContext* context) {
	CrossfireEvent eventObj;
	eventObj.setName(EVENT_CONTEXTDESTROYED);
	eventObj.setContextId(&std::wstring(context->getName()));
	sendEvent(&eventObj);
}

void CrossfireServer::eventContextLoaded(CrossfireContext* context) {
	CrossfireEvent eventObj;
	eventObj.setName(EVENT_CONTEXTLOADED);
	eventObj.setContextId(&std::wstring(context->getName()));
	Value data;
	data.addObjectValue(KEY_HREF, &Value(&std::wstring(context->getHref())));
	eventObj.setData(&data);
	sendEvent(&eventObj);
}
