/**
 * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript.
 * *
 * Copyright (C) 2011, 2012 Loic J. Duros
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see  <http://www.gnu.org/licenses/>.
 *
 */
var {Cc, Ci, Cu, Cm, Cr} = require("chrome");

const processResponse = require('http_observer/process_response');


var streamLoader = {

    loader: null,
    
    listener: null,

    originalListener: null,

    setOriginalListener: function (listener) {
        this.originalListener = listener;
    },

    init: function () {

        try {

            var that = this;
            this.listener = new StreamListener();
            
            this.listener.callback = function (loader, context, status, data) { 

               var responseInfo = {'request': loader.channel,
			            'context': context, 
			            'statusCode': status,
                                    'receivedData': data};
	        var responseHandler = processResponse.ProcessResponse(that.originalListener, responseInfo);        
	        responseHandler.processAllTypes();
                
                that.destroy();
            };

            this.loader = Cc["@mozilla.org/network/unichar-stream-loader;1"].
                createInstance(Ci.nsIUnicharStreamLoader);

            this.loader.init(this.listener);
        } catch (e) {
            console.log(e);
        }

        
    },
    
    destroy: function () {
        this.loader = null;
        this.listener = null;
    }

};

var getRegexForContentType = function (contentType) {
    if (/xhtml/i.test(contentType)) {
            return /<\?[^>]*?encoding=(?:["']*)([^"'\s\?>]+)(?:["']*)/i;        
    }

    // return the regular html regexp for anything else.
    return /<meta[^>]*?charset=(?:["']*)([^"'\s>]+)(?:["']*)/i;
};

function StreamListener () {}

StreamListener.prototype = {

    QueryInterface: function listener_qi(iid) {
        if (iid.equals(Ci.nsISupports) ||
            iid.equals(Ci.nsIUnicharStreamLoaderObserver)) {
            return this;
        }
        throw Cr.NS_ERROR_NO_INTERFACE;
    },

    onStreamComplete : function onStreamComplete (loader, context, status, data) {
        this.callback(loader, context, status, data);      
    },
    onDetermineCharset: function onDetermineCharset(loader, context, data) {
        var match, regex;
        if (loader.channel.contentCharset != undefined && loader.channel.contentCharset != "") {
            return loader.channel.contentCharset;
        } else {
            match = getRegexForContentType(loader.channel.contentType).exec(data);
            if (match) {
                loader.channel.contentCharset = match[1];
                return match[1];
            } else {
                return "UTF-8";
            }

        }
    }
};

exports.streamLoader = function () {
    var l = Object.create(streamLoader);
    l.init();
    return l;
};