/* ************************************************************************
#
#  DivConq
#
#  http://divconq.com/
#
#  Copyright:
#    Copyright 2012 eTimeline, LLC. All rights reserved.
#
#  License:
#    See the license.txt file in the project's top-level directory for details.
#
#  Authors:
#    * Andy White
#
************************************************************************ */
package divconq.collab;

import divconq.api.ApiBase;
import divconq.bus.IServiceResponse;
import divconq.bus.ServiceResponse;
import divconq.bus.Message;
import divconq.struct.CompositeStruct;
import divconq.struct.FieldStruct;
import divconq.struct.RecordStruct;

public class CollaboratorClient {
	protected ApiBase apiConn = null;
	
	protected String id = null;
	protected String access = null;
	protected String hub = null;
	
	public String getId() {
		return this.id;
	}
	
	public String getAccessCode() {
		return this.access;
	}
	
	public String getHub() {
		return this.hub;
	}
	
	public CollaboratorClient(ApiBase conn) {		
		this.apiConn = conn;
	}
	
	public CollaboratorClient(ApiBase conn, String id, String accesscode, String hubid) {
		this.apiConn = conn;
		this.id = id;
		this.access = accesscode;
		this.hub = hubid;
	}
	
	public CollaboratorClient(CollaboratorClient clone) {
		this.id = clone.id;
		this.access = clone.access;
		this.hub = clone.hub;
	}
	
	public void call(CompositeStruct request, ICollabCallback callback) {
		Message msg = new Message("Collaborator");
		
		if (this.id == null) {
			msg.setField("Feature", "Manager");
			msg.setField("Op", "Start");
			
			msg.setField("Body", new RecordStruct(
					new FieldStruct("Batch", request)
				)
			);
		}
		else {
			msg.setField("Feature", "Session");
			msg.setField("ToHub", this.hub);
			
			msg.setField("Body", new RecordStruct(
					new FieldStruct("AccessCode", this.access),
					new FieldStruct("Id", this.id),
					new FieldStruct("Batch", request)
				)
			);
		}

		this.send(msg, callback);
	}
	
	private void send(Message msg, final ICollabCallback callback) {
		IServiceResponse cb = new ServiceResponse() {
			@Override
			public void safeResponse(Message msg) {
				Long res = msg.getFieldAsInteger("Result");
				
				if ((res == null) || (res == 0)) {				
					RecordStruct resp = msg.getFieldAsRecord("Body");
					
					// no response body if END session
					if (resp == null)
						return;
					
					CollaboratorClient.this.hub = msg.getFieldAsString("FromHub");					
					CollaboratorClient.this.id = resp.getFieldAsString("Id");
					CollaboratorClient.this.access = resp.getFieldAsString("AccessCode");
					
					if (callback != null)
						callback.success(resp, msg.getFieldAsComposite("Messages"));
				}
				else {					
					if (callback != null)
						callback.fail(res, msg.getFieldAsString("Message"), msg.getFieldAsComposite("Messages"));					
				}
			}
		};

		this.sendPipe(msg, cb);
	}
	
	protected void sendPipe(Message msg, IServiceResponse cb) {
		cb.response(this.apiConn.sendMessage(msg));
	}

	public void end() {
		Message msg = new Message("Collaborator");
		msg.setField("Feature", "Manager");
		msg.setField("Op", "End");
		msg.setField("ToHub", this.hub);
		
		msg.setField("Body", new RecordStruct(
				new FieldStruct("AccessCode", this.access),
				new FieldStruct("Id", this.id)
			)
		);

		this.send(msg, null);
	}
}
