/*******************************************************************************
 * Copyright (c) 2010 Nokia 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:
 * Nokia - Initial API and implementation
 *******************************************************************************/
#include "EventClientNotifier.h"
#include "TCFHeaders.h"
#include "Logger.h"
#include "AgentUtils.h"
#include "TCFOutputStream.h"
#include "ProtocolConstants.h"
#include "ThreadContext.h"
#include "ContextManager.h"

extern void debug_session_ends();

TCFBroadcastGroup * EventClientNotifier::broadcastGroup = NULL;

static const char RUN_CONTROL[] = "RunControl";

SendRemovedEventParams::SendRemovedEventParams(Context* context_, bool delete_) {
	context = context_;
	deleteContext = delete_;
}

SendExeEventParams::SendExeEventParams(Context* context_, unsigned long pcAddress_, const Properties& properties_) {
	context = context_;
	properties = properties_;
	pcAddress = pcAddress_;
}

SendExceptionEventParams::SendExceptionEventParams(Context* context_,
		const std::string& description_) {
	context = context_;
	description = description_;
}

SendSuspendEventParams::SendSuspendEventParams(Context* context_, unsigned long pcAddress_,
		const char* reason_, const std::string& message_) {
	context = context_;
	pcAddress = pcAddress_;
	reason = reason_;
	message = message_;
}

void EventClientNotifier::SendContextAdded(Context* context) {
	post_event(EventClientNotifier::SendContextAddedCallback, context);
}

void EventClientNotifier::SendContextAddedCallback(void* context) {
	TCFOutputStream out(&broadcastGroup->out);

	out.writeStringZ("E");
	out.writeStringZ(RUN_CONTROL);
	out.writeStringZ("contextAdded");

	// <array of context data>
	out.writeCharacter('[');
	WriteContext(*(Context*) context, out);
	out.writeCharacter(']');
	out.writeZero();

	out.writeComplete();

	std::string contextID = ((Context*) context)->GetID();

	LogTrace("EventClientNotifier::SendContextAdded ", "context id: %s",
			contextID.c_str());

}

void EventClientNotifier::SendContextRemoved(Context* context, bool deleteContext) {
	SendRemovedEventParams* params = new SendRemovedEventParams(context, deleteContext);
	post_event(EventClientNotifier::SendContextRemovedCallback, params);
}

void EventClientNotifier::SendContextRemovedCallback(void* context) {
	SendRemovedEventParams* params = (SendRemovedEventParams*) context;
	TCFOutputStream out(&broadcastGroup->out);

	out.writeStringZ("E");
	out.writeStringZ(RUN_CONTROL);
	out.writeStringZ("contextRemoved");

	/* <array of context data> */
	out.writeCharacter('[');
	out.writeString(params->context->GetID().c_str());
	out.writeCharacter(']');
	out.writeZero();

	out.writeComplete();

	LogTrace("EventClientNotifier::SendContextRemoved ", "context id: %d",
			params->context->GetID().c_str());

	if (params->deleteContext) {
		ContextID id = params->context->GetID();
		delete params->context; // this will delete the context and all its children

		int remained = ContextManager::getContexts().size();
		trace(LOG_CONTEXT, "Context %s has died. \n\t\tNumber of contexts remained: %d\n", id.c_str(), remained);

		if (remained == 0) {
			debug_session_ends();
		}
	}

	delete params;

}

void EventClientNotifier::SendExecutableEvent(Context* context, unsigned long pcAddress, const Properties& properties) { 
	post_event(EventClientNotifier::SendExecutableEventCallback,
			new SendExeEventParams(context, pcAddress, properties));
}

void EventClientNotifier::SendExecutableEventCallback(void* params) {
	SendExeEventParams* eventParams = (SendExeEventParams*) params;

	TCFOutputStream out(&broadcastGroup->out);

	out.writeStringZ("E");
	out.writeStringZ(RUN_CONTROL);
	out.writeStringZ("contextSuspended");

	out.writeString(eventParams->context->GetID());
	out.writeZero();

	out.writeLong(eventParams->pcAddress);
	out.writeZero();

	out.writeString(REASON_SHAREDLIB);
	out.writeZero();

	WriteProperties(eventParams->properties, out);

	out.writeZero();

	out.writeComplete();

#if ENABLE_Trace
	PropertyValue exe;
	Properties::const_iterator iter = eventParams->properties.find(PROP_NAME);
	if (iter != eventParams->properties.end())
		exe = iter->second;
	LogTrace("EventClientNotifier::SendExecutableEvent",
			"context id: %s executable: %s address: %X",
			eventParams->context->GetID().c_str(),
			exe.getType() == PVT_UNKNOWN ? exe.getStringValue().c_str() : "<none>",
			eventParams->pcAddress);
#endif
	
	delete eventParams;
}

void EventClientNotifier::SendContextSuspended(Context* context,
		unsigned long pcAddress, const char* reason, const std::string& message) {
	post_event(EventClientNotifier::SendContextSuspendedCallback,
			new SendSuspendEventParams(context, pcAddress, reason, message));
}

void EventClientNotifier::SendContextSuspendedCallback(void* params_) {
	SendSuspendEventParams* params = (SendSuspendEventParams*) params_;
	TCFOutputStream out(&broadcastGroup->out);

	out.writeStringZ("E");
	out.writeStringZ(RUN_CONTROL);
	out.writeStringZ("contextSuspended");

	out.writeString(params->context->GetID().c_str());
	out.writeZero();

	out.writeLong(params->pcAddress);
	out.writeZero();

	out.writeString(params->reason);
	out.writeZero();

	out.writeCharacter('{');
	if (params->message.length() > 0) {
		out.writeString("message");
		out.writeCharacter(':');
		out.writeString(params->message.c_str());
	}
	out.writeCharacter('}');
	out.writeZero();

	out.writeComplete();

	LogTrace("EventClientNotifier::SendContextSuspended ",
			"context id: %s address: %X", params->context->GetID().c_str(),
			params->pcAddress);

	delete params;
}



void EventClientNotifier::SendContextException(Context* context,
		const std::string& description) {
	post_event(EventClientNotifier::SendContextExceptionCallback,
			new SendExceptionEventParams(context, description));
}

void EventClientNotifier::SendContextExceptionCallback(void* params) {
	SendExceptionEventParams* eventParams = (SendExceptionEventParams*) params;

	TCFOutputStream out(&broadcastGroup->out);

	out.writeStringZ("E");
	out.writeStringZ(RUN_CONTROL);
	out.writeStringZ("contextException");

	out.writeString(eventParams->context->GetID());
	out.writeZero();

	out.writeCharacter('"');
	out.writeString(eventParams->description.c_str());
	out.writeCharacter('"');
	out.writeZero();

	out.writeComplete();

	LogTrace("EventClientNotifier::SendContextException ", "context id: %s",
			eventParams->context->GetID().c_str());

	delete eventParams;
}

void EventClientNotifier::WriteContext(Context& context, TCFOutputStream& out) {
	WriteProperties(context.GetProperties(), out);
}

void EventClientNotifier::WriteProperties(const Properties& properties, TCFOutputStream& out) {
	out.writeCharacter('{');

	for (Properties::const_iterator iter = properties.begin();
			iter != properties.end(); iter++)
	{
		if (iter != properties.begin())
			out.writeCharacter(',');

		out.writeString(iter->first);
		out.writeCharacter(':');
		iter->second.writeToTCFChannel(out);
	}

	out.writeCharacter('}');
}
