/*
 * @author: Jeff Thompson
 * See COPYING for copyright and distribution information.
 * This is the ndn protocol handler.
 * 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");
Components.utils.import("chrome://modules/content/NdnProtocolInfo.jsm");

function NdnProtocol() {
    // TODO: Remove host: null when null is the default.
    this.ndn = new NDN({ getTransport: function() { return new XpcomTransport(); }, 
        host: null, verify: false });
}

NdnProtocol.prototype = {
    scheme: "ndn",
    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);

        // We have to trim now because nsIURI converts spaces to %20 and we can't trim in newChannel.
        var uriParts = NdnProtocolInfo.splitUri(aSpec);
        if (aBaseURI == null || uriParts.name.length < 1 || uriParts.name[0] == '/')
            // Just reconstruct the trimmed URI.
            uri.spec = "ndn:" + uriParts.name + uriParts.search + uriParts.hash;
        else {
            // Make a URI relative to the base name up to the file name component.
            var baseUriParts = NdnProtocolInfo.splitUri(aBaseURI.spec);
            var baseName = new Name(baseUriParts.name);
            var iFileName = baseName.indexOfFileName();
            
            var relativeName = uriParts.name;
            // Handle ../
            while (true) {
                if (relativeName.substr(0, 2) == "./")
                    relativeName = relativeName.substr(2);
                else if (relativeName.substr(0, 3) == "../") {
                    relativeName = relativeName.substr(3);
                    if (iFileName > 0)
                        --iFileName;
                }
                else
                    break;
            }
            
            var prefixUri = "/";
            if (iFileName > 0)
                prefixUri = new Name(baseName.components.slice(0, iFileName)).to_uri() + "/";
            uri.spec = "ndn:" + prefixUri + relativeName + uriParts.search + uriParts.hash;
        }
        
        return uri;
    },

    newChannel: function(aURI)
    {
        var thisNdnProtocol = this;
        
        try {            
            var uriParts = NdnProtocolInfo.splitUri(aURI.spec);
    
            var template = new Interest(new Name([]));
            // Use the same default as NDN.expressInterest.
            template.interestLifetime = 4000; // milliseconds
            var searchWithoutNdn = extractNdnSearch(uriParts.search, template);
            
            var segmentTemplate = new Interest(new Name([]));
            // Only use the interest selectors which make sense for fetching further segments.
            segmentTemplate.publisherPublicKeyDigest = template.publisherPublicKeyDigest;
            segmentTemplate.scope = template.scope;
            segmentTemplate.interestLifetime = template.interestLifetime;
    
            var requestContent = function(contentListener) {                
                var name = new Name(uriParts.name);
                // TODO: Strip off an ending implicit digest before checking the last component?
                var uriEndsWithSegmentNumber = endsWithSegmentNumber(name);
                
                // Use the same NDN object each time.
                thisNdnProtocol.ndn.expressInterest(name, 
                    new ContentClosure(thisNdnProtocol.ndn, contentListener, uriEndsWithSegmentNumber, 
                            aURI.originCharset, searchWithoutNdn + uriParts.hash, segmentTemplate),
                    template);
            };

            return new ContentChannel(aURI, requestContent);
        } catch (ex) {
            dump("NdnProtocol.newChannel exception: " + ex + "\n" + ex.stack);
        }
    },

    classDescription: "ndn Protocol Handler",
    contractID: "@mozilla.org/network/protocol;1?name=" + "ndn",
    classID: Components.ID('{8122e660-1012-11e2-892e-0800200c9a66}'),
    QueryInterface: XPCOMUtils.generateQI([Ci.nsIProtocolHandler])
};

if (XPCOMUtils.generateNSGetFactory)
    var NSGetFactory = XPCOMUtils.generateNSGetFactory([NdnProtocol]);
else
    var NSGetModule = XPCOMUtils.generateNSGetModule([NdnProtocol]);
                
/*
 * Create a closure for calling expressInterest.
 * contentListener is from the call to requestContent.
 * uriEndsWithSegmentNumber is true if the URI passed to newChannel has a segment number
 *    (used to determine whether to request only that segment number and for updating the URL bar).
 * uriOriginCharset is the charset of the URI passed to newChannel (used for making a new URI)
 * uriSearchAndHash is the search and hash part of the URI passed to newChannel, including the '?'
 *    and/or '#' but without the interest selector fields.
 * segmentTemplate is the template used in expressInterest to fetch further segments.
 */                                                
var ContentClosure = function ContentClosure
        (ndn, contentListener, uriEndsWithSegmentNumber, uriOriginCharset, uriSearchAndHash, 
         segmentTemplate) {
    // Inherit from Closure.
    Closure.call(this);
    
    this.ndn = ndn;
    this.contentListener = contentListener;
    this.uriEndsWithSegmentNumber = uriEndsWithSegmentNumber;
    this.uriOriginCharset = uriOriginCharset;
    this.uriSearchAndHash = uriSearchAndHash;
    this.segmentTemplate = segmentTemplate;
    
    this.segmentStore = new SegmentStore();
    this.contentSha256 = new Sha256();
    this.didRequestFinalSegment = false;
    this.finalSegmentNumber = null;
};

ContentClosure.prototype.upcall = function(kind, upcallInfo) {
  try {
    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("NdnProtocol.ContentClosure: contentObject.content is null\n");
        return Closure.RESULT_ERR;
    }
    
    // Now that we're connected, report the host and port.
    NdnProtocolInfo.setConnectedNdnHub(this.ndn.host, this.ndn.port);

    // If !this.uriEndsWithSegmentNumber, we use the segmentNumber to load multiple segments.
    // If this.uriEndsWithSegmentNumber, then we leave segmentNumber null.
    var segmentNumber = null;
    if (!this.uriEndsWithSegmentNumber && endsWithSegmentNumber(contentObject.name)) {
        segmentNumber = DataUtils.bigEndianToUnsignedInt
            (contentObject.name.components[contentObject.name.components.length - 1]);
        this.segmentStore.storeContent(segmentNumber, contentObject);
    }
    
    if (segmentNumber == null || segmentNumber == 0) {
        // This is the first or only segment, so start.
        // Get the URI from the ContentObject including the version.
        var contentUriSpec;
        if (!this.uriEndsWithSegmentNumber && endsWithSegmentNumber(contentObject.name)) {
            var nameWithoutSegmentNumber = new Name
                (contentObject.name.components.slice(0, contentObject.name.components.length - 1));
            contentUriSpec = "ndn:" + nameWithoutSegmentNumber.to_uri();
        }
        else
            contentUriSpec = "ndn:" + contentObject.name.to_uri();
    
        // Include the search and hash.
        contentUriSpec += this.uriSearchAndHash;
    
        var contentTypeEtc = getNameContentTypeAndCharset(contentObject.name);
        var ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
        this.contentListener.onStart(contentTypeEtc.contentType, contentTypeEtc.contentCharset, 
            ioService.newURI(contentUriSpec, this.uriOriginCharset, null));
    }

    if (segmentNumber == null) {
        // We are not doing segments, so just finish.
        this.contentListener.onReceivedContent(DataUtils.toString(contentObject.content));
        this.contentSha256.update(contentObject.content);
        this.contentListener.onStop();

        if (!this.uriEndsWithSegmentNumber) {
            var nameContentDigest = contentObject.name.getContentDigestValue();
            if (nameContentDigest != null &&
                !DataUtils.arraysEqual(nameContentDigest, this.contentSha256.finalize()))
                // TODO: How to show the user an error for invalid digest?
                dump("Content does not match digest in name " + contentObject.name.to_uri());
        }
        return Closure.RESULT_OK;
    }
    
    if (contentObject.signedInfo != null && contentObject.signedInfo.finalBlockID != null)
        this.finalSegmentNumber = DataUtils.bigEndianToUnsignedInt(contentObject.signedInfo.finalBlockID);

    // The content was already put in the store.  Retrieve as much as possible.
    var entry;
    while ((entry = this.segmentStore.maybeRetrieveNextEntry()) != null) {
        segmentNumber = entry.key;
        contentObject = entry.value;
        this.contentListener.onReceivedContent(DataUtils.toString(contentObject.content));
        this.contentSha256.update(contentObject.content);
        
        if (this.finalSegmentNumber != null && segmentNumber == this.finalSegmentNumber) {
            // Finished.
            this.contentListener.onStop();
            var nameContentDigest = contentObject.name.getContentDigestValue();
            if (nameContentDigest != null &&
                !DataUtils.arraysEqual(nameContentDigest, this.contentSha256.finalize()))
                // TODO: How to show the user an error for invalid digest?
                dump("Content does not match digest in name " + contentObject.name.to_uri());

            return Closure.RESULT_OK;
        }
    }

    if (this.finalSegmentNumber == null && !this.didRequestFinalSegment) {
        this.didRequestFinalSegment = true;
        // Try to determine the final segment now.
        var components = contentObject.name.components.slice
            (0, contentObject.name.components.length - 1);
            
        // Temporarily set the childSelector in the segmentTemplate.
        this.segmentTemplate.childSelector = 1;
        this.ndn.expressInterest(new Name(components), this, this.segmentTemplate);
        this.segmentTemplate.childSelector = null;
    }

    // Request new segments.
    var toRequest = this.segmentStore.requestSegmentNumbers(2);
    for (var i = 0; i < toRequest.length; ++i) {
        if (this.finalSegmentNumber != null && toRequest[i] > this.finalSegmentNumber)
            continue;
        
        // Make a name for the segment and get it.
        var segmentNumberBigEndian = DataUtils.nonNegativeIntToBigEndian(toRequest[i]);
        // Put a 0 byte in front.
        var segmentNumberComponent = new Uint8Array(segmentNumberBigEndian.length + 1);
        segmentNumberComponent.set(segmentNumberBigEndian, 1);
        
        var components = contentObject.name.components.slice
            (0, contentObject.name.components.length - 1);
        components.push(segmentNumberComponent);
        this.ndn.expressInterest(new Name(components), this, this.segmentTemplate);
    }
        
    return Closure.RESULT_OK;
  } catch (ex) {
        dump("ContentClosure.upcall exception: " + ex + "\n" + ex.stack);
        return Closure.RESULT_ERR;
  }
};

/*
 * A SegmentStore stores segments until they are retrieved in order starting with segment 0.
 */
var SegmentStore = function SegmentStore() {
    // Each entry is an object where the key is the segment number and value is null if
    //   the segment number is requested or the contentObject if received.
    this.store = new SortedArray();
    this.maxRetrievedSegmentNumber = -1;
};

SegmentStore.prototype.storeContent = function(segmentNumber, contentObject) {
    // We don't expect to try to store a segment that has already been retrieved, but check anyway.
    if (segmentNumber > this.maxRetrievedSegmentNumber)
        this.store.set(segmentNumber, contentObject);
};

/*
 * If the min segment number is this.maxRetrievedSegmentNumber + 1 and its value is not null, 
 *   then delete from the store, return the entry with key and value, and update maxRetrievedSegmentNumber.  
 * Otherwise return null.
 */
SegmentStore.prototype.maybeRetrieveNextEntry = function() {
    if (this.store.entries.length > 0 && this.store.entries[0].value != null &&
        this.store.entries[0].key == this.maxRetrievedSegmentNumber + 1) {
        var entry = this.store.entries[0];
        this.store.removeAt(0);
        ++this.maxRetrievedSegmentNumber;
        return entry;
    }
    else
        return null;
};

/*
 * Return an array of the next segment numbers that need to be requested so that the total
 *   requested segments is totalRequestedSegments.  If a segment store entry value is null, it is
 *   already requested and is not returned.  If a segment number is returned, create a
 *   entry in the segment store with a null value.
 */
SegmentStore.prototype.requestSegmentNumbers = function(totalRequestedSegments) {
    // First, count how many are already requested.
    var nRequestedSegments = 0;
    for (var i = 0; i < this.store.entries.length; ++i) {
        if (this.store.entries[i].value == null) {
            ++nRequestedSegments;
            if (nRequestedSegments >= totalRequestedSegments)
                // Already maxed out on requests.
                return [];
        }
    }
    
    var toRequest = [];
    var nextSegmentNumber = this.maxRetrievedSegmentNumber + 1;
    for (var i = 0; i < this.store.entries.length; ++i) {
        var entry = this.store.entries[i];
        // Fill in the gap before the segment number in the entry.
        while (nextSegmentNumber < entry.key) {
            toRequest.push(nextSegmentNumber);
            ++nextSegmentNumber;
            ++nRequestedSegments;
            if (nRequestedSegments >= totalRequestedSegments)
                break;
        }
        if (nRequestedSegments >= totalRequestedSegments)
            break;
        
        nextSegmentNumber = entry.key + 1;
    }
    
    // We already filled in the gaps for the segments in the store. Continue after the last.
    while (nRequestedSegments < totalRequestedSegments) {
        toRequest.push(nextSegmentNumber);
        ++nextSegmentNumber;
        ++nRequestedSegments;
    }
    
    // Mark the new segment numbers as requested.
    for (var i = 0; i < toRequest.length; ++i)
        this.store.set(toRequest[i], null);
    return toRequest;
}

/*
 * A SortedArray is an array of objects with key and value, where the key is an integer.
 */
var SortedArray = function SortedArray() {
    this.entries = [];
}

SortedArray.prototype.sortEntries = function() {
    this.entries.sort(function(a, b) { return a.key - b.key; });
};

SortedArray.prototype.indexOfKey = function(key) {
    for (var i = 0; i < this.entries.length; ++i) {
        if (this.entries[i].key == key)
            return i;
    }

    return -1;
}

SortedArray.prototype.set = function(key, value) {
    var i = this.indexOfKey(key);
    if (i >= 0) {
        this.entries[i].value = value;
        return;
    }
    
    this.entries.push({ key: key, value: value});
    this.sortEntries();
}

SortedArray.prototype.removeAt = function(index) {
    this.entries.splice(index, 1);
}

/*
 * Scan the name from the last component to the first (skipping special name components)
 *   for a recognized file name extension, and return an object with properties contentType and charset.
 */
function getNameContentTypeAndCharset(name) {
    var iFileName = name.indexOfFileName();
    if (iFileName < 0)
        // Get the default mime type.
        return MimeTypes.getContentTypeAndCharset("");
    
    return MimeTypes.getContentTypeAndCharset
        (DataUtils.toString(name.components[iFileName]).toLowerCase());
}

/*
 * Return true if the last component in the name is a segment number..
 */
function endsWithSegmentNumber(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;
}

/*
 * Find all search keys starting with "ndn." and set the attribute in template.
 * Return the search string including the starting "?" but with the "ndn." keys removed,
 *   or return "" if there are no search terms left.
 */
function extractNdnSearch(search, template) {
    if (!(search.length >= 1 && search[0] == '?'))
        return search;
    
    var terms = search.substr(1).split('&');
    var i = 0;
    while (i < terms.length) {
        var keyValue = terms[i].split('=');
        var key = keyValue[0].trim();
        if (key.substr(0, 4) == "ndn.") {
            if (keyValue.length >= 1) {
                var value = keyValue[1].trim();
                var nonNegativeInt = parseInt(value);
                
                if (key == "ndn.MinSuffixComponents" && nonNegativeInt >= 0)
                    template.minSuffixComponents = nonNegativeInt;
                if (key == "ndn.MaxSuffixComponents" && nonNegativeInt >= 0)
                    template.maxSuffixComponents = nonNegativeInt;
                if (key == "ndn.ChildSelector" && nonNegativeInt >= 0)
                    template.childSelector = nonNegativeInt;
                if (key == "ndn.AnswerOriginKind" && nonNegativeInt >= 0)
                    template.answerOriginKind = nonNegativeInt;
                if (key == "ndn.Scope" && nonNegativeInt >= 0)
                    template.scope = nonNegativeInt;
                if (key == "ndn.InterestLifetime" && nonNegativeInt >= 0)
                    template.interestLifetime = nonNegativeInt;
                if (key == "ndn.PublisherPublicKeyDigest" && nonNegativeInt >= 0)
                    template.publisherPublicKeyDigest = DataUtils.toNumbersFromString(unescape(value));
                if (key == "ndn.Nonce" && nonNegativeInt >= 0)
                    template.nonce = DataUtils.toNumbersFromString(unescape(value));
                // TODO: handle Exclude.
            }
        
            // Remove the "ndn." term and don't advance i.
            terms.splice(i, 1);
        }
        else
            ++i;
    }
    
    if (terms.length == 0)
        return "";
    else
        return "?" + terms.join('&');
}
