
/*
 * 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
 */

requireClass ./Weinre
requireClass ./WebSocketXhr
requireClass ./IDLTools
requireClass ./Binding
requireClass ./Ex

//-----------------------------------------------------------------------------
class MessageDispatcher(url)
    this._url        = url
    
    this.error       = null
    this._opening    = false
    this._opened     = false
    this._closed     = false
    this._interfaces = {}
    
    this._open()

//-----------------------------------------------------------------------------
init
    var Verbose = false
    var InspectorBackend

//-----------------------------------------------------------------------------
static method setInspectorBackend(inspectorBackend)
    InspectorBackend = inspectorBackend
    
//-----------------------------------------------------------------------------
static method verbose(value)
    if (arguments.length >= 1) {
        Verbose = !!value
    }
    
    return Verbose

//-----------------------------------------------------------------------------
method _open
    if (this._opened || this._opening) return
    if (this._closed) throw new Ex(arguments, "socket has already been closed")
    
    this._opening = true 
    this._socket = new WebSocketXhr(this._url)
    this._socket.addEventListener("open",    Binding(this, "_handleOpen"))
    this._socket.addEventListener("error",   Binding(this, "_handleError"))
    this._socket.addEventListener("message", Binding(this, "_handleMessage"))
    this._socket.addEventListener("close",   Binding(this, "_handleClose"))

//-----------------------------------------------------------------------------
method close
    if (this._closed) return
    
    this._opened = false
    this._closed = true
    
    this._socket.close()

//-----------------------------------------------------------------------------
method send(data)
    this._socket.send(data)

//-----------------------------------------------------------------------------
method getWebSocket
    return this._socket

//-----------------------------------------------------------------------------
method registerInterface(intfName, intf, validate)
    if (validate) IDLTools.validateAgainstIDL(intf.constructor, intfName)
    
    if (this._interfaces[intfName]) throw new Ex(arguments, "interface " + intfName + " has already been registered")
    
    this._interfaces[intfName] = intf

//-----------------------------------------------------------------------------
method createProxy(intfName)
    var proxy = {}
    
    IDLTools.buildProxyForIDL(proxy, intfName)

    var self = this
    proxy.__invoke = function __invoke(intfName, methodName, args) {
        self._sendMethodInvocation(intfName, methodName, args)
    }
    
    return proxy

//-----------------------------------------------------------------------------
method _sendMethodInvocation(intfName, methodName, args)
    if (typeof intfName   != "string") throw new Ex(arguments, "expecting intf parameter to be a string")
    if (typeof methodName != "string") throw new Ex(arguments, "expecting method parameter to be a string")
    
    var data = {
            "interface": intfName,
            "method":    methodName,
            "args":      args
    }
    
    data = JSON.stringify(data)
    
    this._socket.send(data)
    
    if (Verbose) {
        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: send " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
    }

//-----------------------------------------------------------------------------
method getState
    if (this._opening) return "opening"
    if (this._opened)  return "opened"
    if (this._closed)  return "closed"
    return "unknown"

//-----------------------------------------------------------------------------
method isOpen
    return this._opened == true

//-----------------------------------------------------------------------------
method _handleOpen
    this._opening = false
    this._opened  = true
    
    if (Verbose) {
        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: opened")
    }

//-----------------------------------------------------------------------------
method _handleError(message)
    this.error = message
    this.close()

    if (Verbose) {
        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: error: " + message)
    }

//-----------------------------------------------------------------------------
method _handleMessage(message)
    var data
    
    try {
        data = JSON.parse(message.data)
    }
    catch (e) {
        throw new Ex(arguments, "invalid JSON data received: " + e + ": '" + message.data + "'")
    }

    var intfName   = data["interface"]
    var methodName = data.method
    var args       = data.args

    var methodSignature = intfName + "." + methodName + "()"
    
    var intf = this._interfaces.hasOwnProperty(intfName) && this._interfaces[intfName]
    
    if (!intf && InspectorBackend && intfName.match(/.*Notify/)) {
        intf = InspectorBackend.getRegisteredDomainDispatcher(intfName.substr(0,intfName.length-6))
    }
    
    if (!intf) {
        Weinre.logWarning("weinre: request for non-registered interface:" + methodSignature)
        return
    }
    
    methodSignature = intf.constructor.name + "." + methodName + "()"
    
    var method = intf[methodName]
    if (typeof method != "function") {
        Weinre.notImplemented(methodSignature)
        return
    }
    
    try {
        method.apply(intf, args)
    }
    catch (e) {
        Weinre.logError("weinre: invocation exception on " + methodSignature + ": " + e)
    }
    
    if (Verbose) {
        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: recv " + intfName + "." + methodName + "(" + JSON.stringify(args) + ")")
    }

//-----------------------------------------------------------------------------
method _handleClose
    this._reallyClosed = true
    
    if (Verbose) {
        Weinre.logDebug(this.constructor.name + "[" + this._url + "]: closed")
    }
