/*
 * @author: ucla-cs
 * See COPYING for copyright and distribution information.
 * This is the ccnx protocol handler for NDN.
 * Protocol handling code derived from http://mike.kaply.com/2011/01/18/writing-a-firefox-protocol-handler/
 */

const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;

const nsIProtocolHandler = Ci.nsIProtocolHandler;

Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("chrome://modules/content/ndn-js.jsm");
Components.utils.import("chrome://modules/content/ContentChannel.jsm");

function CcnxProtocol() {
}

CcnxProtocol.prototype = {
	scheme: "ccnx",
	protocolFlags: nsIProtocolHandler.URI_NORELATIVE |
                   nsIProtocolHandler.URI_NOAUTH |
                   nsIProtocolHandler.URI_LOADABLE_BY_ANYONE,

	newURI: function(aSpec, aOriginCharset, aBaseURI)
	{
		var uri = Cc["@mozilla.org/network/simple-uri;1"].createInstance(Ci.nsIURI);
		uri.spec = aSpec;
		return uri;
	},

	newChannel: function(aURI)
	{
		try {
            var trimmedSpec = aURI.spec.trim();
            
            // Save the mostRecentWindow from the moment of newChannel.
    		var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
    		var mostRecentWindow = wm.getMostRecentWindow("navigator:browser");
    
			var requestContent = function(contentListener) {
                // Set nameString to the URI without the protocol.
                var nameString = trimmedSpec;
                var colonIndex = nameString.indexOf(':');
                if (colonIndex >= 0)
                    nameString = nameString.substr
                        (colonIndex + 1, nameString.length - colonIndex - 1).trim();
                
				var name = new Name(nameString);
                // TODO: Strip off an ending implicit digest before checking the last component?
                var uriEndsWithSequence = endsWithSequence(name);
                
			    // 131.179.141.18 is lioncub.metwi.ucla.edu .
				var ndn = new NDN('131.179.141.18');
                				
				var ContentClosure = function ContentClosure() {
                    // Inherit from Closure.
                    Closure.call(this);
                }
                ContentClosure.prototype.upcall = function(kind, upcallInfo) {
                    if (!(kind == Closure.UPCALL_CONTENT ||
                          kind == Closure.UPCALL_CONTENT_UNVERIFIED))
                        // The upcall is not for us.
                        return Closure.RESULT_ERR;
                        
                    var contentObject = upcallInfo.contentObject;
                    if (contentObject.content == null) {
                        dump("CcnxProtocol.newChannel: contentObject.content is null\n");
                        return Closure.RESULT_ERR;
                    }
                        
                    var content = DataUtils.toString(contentObject.content);
                    var contentTypeEtc = getContentTypeAndCharset(contentObject.name);						
					contentListener.onReceivedContent(content, 
                        contentTypeEtc.contentType, contentTypeEtc.contentCharset);
                    
                    // Assume that onReceivedContent sends all the content immediately and updatse
                    //   the gURLBar if the content is for the main window.
                    var urlBar = mostRecentWindow.gURLBar;
                    if (urlBar && urlBar.value.trim() == trimmedSpec) {
                        // Assume the URI is for the window.  Update the URL bar.
                        // Show the name without the ending sequence (unless the original URI had it).
                        if (!uriEndsWithSequence && endsWithSequence(contentObject.name)) {
                            var nameWithoutSequence = new Name
                                (contentObject.name.components.slice
                                 (0, contentObject.name.components.length - 1));
                            urlBar.value = "ccnx:" + nameWithoutSequence.to_uri();
                        }
                        else
                            urlBar.value = "ccnx:" + contentObject.name.to_uri();
                    }
                    
                    return Closure.RESULT_OK;
				};
			
				ndn.expressInterest(name, new ContentClosure());
			};

			return new ContentChannel(aURI, requestContent);
		} catch (ex) {
			dump("CcnxProtocol.newChannel exception: " + ex + "\n");
		}
	},

	classDescription: "ccnx Protocol Handler",
	contractID: "@mozilla.org/network/protocol;1?name=" + "ccnx",
	classID: Components.ID('{8122e660-1012-11e2-892e-0800200c9a66}'),
	QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
}

if (XPCOMUtils.generateNSGetFactory)
	var NSGetFactory = XPCOMUtils.generateNSGetFactory([CcnxProtocol]);
else
	var NSGetModule = XPCOMUtils.generateNSGetModule([CcnxProtocol]);
 
/*
 * Scan the name from the last component to the first (skipping special CCNx components)
 *   for a recognized file name extension, and return an object with properties contentType and charset.
 */
function getContentTypeAndCharset(name) {
    for (var i = name.components.length - 1; i >= 0; --i) {
        var component = name.components[i];
        if (component.length <= 0)
            continue;
        
        // Skip special components which just may have ".gif", etc.
        if (component[0] == 0 || component[0] == 0xC0 || component[0] == 0xC1 || 
            (component[0] >= 0xF5 && component[0] <= 0xFF))
            continue;
        
        var str = DataUtils.toString(component).toLowerCase();
        if (str.indexOf(".gif") >= 0) 
            return { contentType: "image/gif", charset: "ISO-8859-1" }
    	else if (str.indexOf(".jpg") >= 0 ||
    			 str.indexOf(".jpeg") >= 0) 
            return { contentType: "image/jpeg", charset: "ISO-8859-1" }
    	else if (str.indexOf(".png") >= 0) 
            return { contentType: "image/png", charset: "ISO-8859-1" }
        else if (str.indexOf(".bmp") >= 0) 
            return { contentType: "image/bmp", charset: "ISO-8859-1" }
    	else if (str.indexOf(".css") >= 0) 
            return { contentType: "text/css", charset: "utf-8" }
    }
    
    // default
    return { contentType: "text/html", charset: "utf-8" };
}

/*
 * Return true if the last component in the name is a sequence..
 */
function endsWithSequence(name) {
    return name.components != null && name.components.length >= 1 &&
        name.components[name.components.length - 1].length >= 1 &&
        name.components[name.components.length - 1][0] == 0;
}