/*
 * weinre is available under *either* the terms of the modified BSD license *or* the
 * MIT License (2008). See http://opensource.org/licenses/alphabetical for full text.
 *
 * Copyright (c) 2010, 2011 IBM Corporation
 */

package weinre.server;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.apache.wink.json4j.JSONException;
import org.apache.wink.json4j.JSONObject;

//-------------------------------------------------------------------
public class Channel {

    static public final String AnonymousId = "anonymous";

    private String                pathPrefix;
    private String                name;
    private String                id;
    private MessageQueue<String>  requestQueue;
    private MessageQueue<String>  responseQueue;
    private boolean               isClosed;
    private Connector             connector;
    private long                  lastRead;
    private Map<String,Object>    serviceMap;
    private String                remoteHost;
    private String                remoteAddress;
    private PrintWriter           messageLog;

    //---------------------------------------------------------------
    public Channel(String pathPrefix, String name, String id, String remoteHost, String remoteAddress) {
        this.pathPrefix         = pathPrefix;
        this.name               = name;
        this.id                 = id;
        this.remoteHost         = remoteHost;
        this.remoteAddress      = remoteAddress;
        this.requestQueue       = new MessageQueue<String>();
        this.responseQueue      = new MessageQueue<String>();
        this.isClosed           = false;
        this.connector          = null;
        this.serviceMap         = new HashMap<String,Object>();
        this.lastRead           = System.currentTimeMillis();
        this.messageLog         = Main.getSettings().getMessageLog();
    }

    //---------------------------------------------------------------
    public Connector getConnector() {
        return connector;
    }

    //---------------------------------------------------------------
    public String getRemoteHost() {
        return remoteHost;
    }

    //---------------------------------------------------------------
    public String getRemoteAddress() {
        return remoteAddress;
    }

    //---------------------------------------------------------------
    protected void _setConnector(Connector connector) {
        this.connector = connector;
    }

    //---------------------------------------------------------------
    public void sendCallback(String intfName, String callbackId, Object... args) throws IOException {
        if (callbackId == null) return;

        List<Object> innerArgs = new ArrayList<Object>();
        innerArgs.add(callbackId);
        innerArgs.add(Arrays.asList(args));

        sendEvent(intfName, "sendCallback", innerArgs.toArray());
    }

    //---------------------------------------------------------------
    public void sendEvent(String intfName, String methodName, Object... args) {
        Main.debug(getName() + ": send " + intfName + "." + methodName + "()");

        JSONObject response = new JSONObject();

        String responseString;
        try {
            response.put("interface", intfName);
            response.put("method", methodName);

            List<Object> passedArgs = new ArrayList<Object>(Arrays.asList(args));

            response.put("args", passedArgs);

            responseString = response.toString();
        }
        catch (JSONException e) {
            Main.warn("IOException serializing message for " + intfName + "." + methodName);
            return;
        }

        this.postResponse(responseString);
    }

    //---------------------------------------------------------------
    public Object getService(String name) {
        try {
            return getService_(name);
        }
        catch (InstantiationException e) {
            throw new RuntimeException(e);
        }
        catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    //---------------------------------------------------------------
    @SuppressWarnings("rawtypes")
    private Object getService_(String name) throws InstantiationException, IllegalAccessException {
        if (serviceMap.containsKey(name)) return serviceMap.get(name);

        String klassName = "weinre.server.service." + name;
        Class  klass = null;
        try {
            klass = Class.forName(klassName);
        }
        catch (ClassNotFoundException e) {
            // Main.debug("service class not found: " + klassName);
            serviceMap.put(name, null);
            return null;
        }

        Object result = klass.newInstance();
        serviceMap.put(name, result);
        // Main.debug("loaded service class: " + klassName);
        return result;
    }

    //---------------------------------------------------------------
    public void close() {
        isClosed = true;
        requestQueue.shutdown();
        responseQueue.shutdown();

        ChannelManager.$.deregisterChannel(name);
    }

    //---------------------------------------------------------------
    public boolean isClosed() {
        return isClosed;
    }

    //---------------------------------------------------------------
    public String getPathPrefix() {
        return pathPrefix;
    }

    //---------------------------------------------------------------
    public String getName() {
        return name;
    }

    //---------------------------------------------------------------
    public String getId() {
        return id;
    }

    //---------------------------------------------------------------
    public long getLastRead() {
        return lastRead;
    }

    //---------------------------------------------------------------
    public void updateLastRead() {
        lastRead = System.currentTimeMillis();
    }

    //---------------------------------------------------------------
    public void postRequest(String json) {
        if (isClosed()) return;

        requestQueue.add(json);
        log(json);
    }

    //---------------------------------------------------------------
    public void postResponse(String json) {
        if (isClosed()) return;

        responseQueue.add(json);
        log(json);
    }

    //---------------------------------------------------------------
    private void log(String json) {
        if (null == messageLog) return;

        JSONObject jObject;
        try {
            jObject = new JSONObject(json);
            jObject.put("_to", getName() + "#" + getId());
        }
        catch (JSONException e) {
            return;
        }

        messageLog.print(jObject.toString(true));
        messageLog.println(",");
    }

    //---------------------------------------------------------------
    public List<String> getRequests(int timeoutSeconds) throws InterruptedException {
        if (isClosed()) return new LinkedList<String>();

        List<String> result = requestQueue.getAll(timeoutSeconds, TimeUnit.SECONDS);

        return result;
    }

    //---------------------------------------------------------------
    public List<String> getResponses(int timeoutSeconds) throws InterruptedException {
        if (isClosed()) return new LinkedList<String>();

        List<String> result = responseQueue.getAll(timeoutSeconds, TimeUnit.SECONDS);

        return result;
    }

    //---------------------------------------------------------------
    public String toString() {
        return getClass().getName() + "{" + pathPrefix + ":" + name + "}";
    }
}
