
package org.appborg;

import java.io.IOException;

import org.appborg.ByteArrayBuffer;
import org.json.JSONException;
import org.json.JSONObject;



public class ABComm {
	
	private String DEFAULT_FROM = "subprocess";
	private String DEFAULT_TO = "js";
	
	private String name;
	private ABEventHandler eventHandler;
	private long nextId;
	
	public ABComm(ABEventHandler eventHandler) {
		this.name = DEFAULT_FROM;
		this.eventHandler = eventHandler;
		nextId = 1;
	}
	
	public ABComm(ABEventHandler eventHandler, String name) {
		this.name = name;
		this.eventHandler = eventHandler;
		nextId = 1;
	}
	
	public void listenLoop() throws JSONException, IOException {
		ByteArrayBuffer data = new ByteArrayBuffer(1000);
		String base64, json;
		ABEvent event;
		int c = System.in.read();
		while (c != -1) {
			if (c != '\n') {
				data.append(c);
			}
			else {
				base64 = new String(data.toByteArray());
				json = new String(Base64.decode(base64, Base64.NO_WRAP));
				event = new ABEvent(this, json);
				
				try {
					eventHandler.handleEvent(event);
				} catch (Exception exception) {
					event.respondError(exception);
				}
				
				data.clear();
			}
			c = System.in.read();
		}
	}
	
	public void send(String method) {
		try {
			send(method, new JSONObject());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	public void send(String method, JSONObject info) throws JSONException {
		send(method, info, DEFAULT_TO);
	}
	
	public void send(String method, JSONObject info, String to) throws JSONException {
		JSONObject e = new JSONObject();
		e.put("method", method);
		e.put("info", info);
		e.put("id", getNewId());
		e.put("from", name);
		e.put("to", to);
		sendJSONObject(e);
	}
	
	protected void respond(ABEvent event, JSONObject result) throws JSONException {
		_respond(event, null, result);
	}
	
	protected void respondError(ABEvent event, JSONObject error) throws JSONException {
		_respond(event, error, null);
	}
	
	private void _respond(ABEvent event, JSONObject error, JSONObject result) throws JSONException {
		JSONObject response = new JSONObject();
		response.put("id", event.id);
		response.put("from", name);
		response.put("to", event.from);
		response.put("error", error);
		response.put("result", result);
		sendJSONObject(response);
	}
	
	private void sendJSONObject(JSONObject x) {
		String json = x.toString();
		byte[] data = json.getBytes();
		String base64 = Base64.encodeToString(data, Base64.NO_WRAP);
		System.out.print(base64 + "\n");
	}
	
	private long getNewId() {
		long id = nextId;
		nextId++;
		return id;
	}
}
