/** 
 * Module Name: RSS
 * Description: Allows to read RSS feeds
 */
var FeedParser = require('feedparser'), 
    request = require('request'), 
    _ = require('underscore')._;

var rss = function(dbot) {
    this.pollInterval = 120000;
    this.titleCache = [];
    var self = this;

    this.internalAPI = {
        'makeRequest': function(id,feed) {
            var fid = id,
                req = request(feed.url),
                feedparser = new FeedParser();

            req.on('error', function (error) {
                if(dbot.config.debugMode) {
                    dbot.say(feed.server,feed.channel,"RSS: Request for RSS feed got an error: "+error+" Start self-destruct sequence.");
                }
            });

            req.on('response', function (res) {
                var stream = this;
                if (res.statusCode !== 200){
                    dbot.say(feed.server,feed.channel,"RSS: RSS server returned status code "+res.statusCode+". Bastard.");
                    return;
                }

                stream.pipe(feedparser);
            });

            feedparser.on('error', function(error) {
                if(dbot.config.debugMode) {
                    dbot.say(feed.server,feed.channel,"RSS: Feedparser encountered an error: "+error+";;; Inform administrator!");
                }
            });

            feedparser.on('readable', function() {
                // This is where the action is!
                var stream = this, 
                    meta = this.meta, // **NOTE** the "meta" is always available in the context of the feedparser instance
                    item;

                while (item = stream.read()) {
                    // If the feed does not give a pubdate for this post, ignore it...
                    if(!item.pubdate) {
                        return;
                    }
                    if(dbot.config.debugMode) {
                        dbot.say(feed.server,feed.channel,"RSS: Should post question: Is "+(item.pubdate.getTime()-feed.lastPosted)+" > 0?");
                    }
                    if(item.pubdate.getTime() - feed.lastPosted > 0) {
                        if(item.pubdate.getTime() > feed.newTime) {
                            feed.newTime = item.pubdate.getTime();
                        }
                        var rss = item;
                        if(dbot.config.debugMode) {
                            dbot.say(feed.server,feed.channel,"RSS: I shall post a new link! PERFECT.");
                        }
                        if(!_.include(self.titleCache, rss.title)) {
                            var options = {
                                uri: 'https://www.googleapis.com/urlshortener/v1/url',
                                method: 'POST',
                                json: {
                                    "longUrl": rss.link
                                }
                            };

                            request(options, function (error, response, body) {
                                if (!error && response.statusCode === 200) {
                                    var rString = "["+feed.name+"] ["+rss.title+"] "; 
                                    if(rss.author !== null && !_.isUndefined(rss.categories[0])) {
                                        rString += "[Post by "+rss.author+" in "+rss.categories[0]+"] ";
                                    }
                                    rString += "- "+body.id;
                                    dbot.say(feed.server,feed.channel, rString);
                                } else {
                                    var rString = "["+feed.name+"] ["+rss.title+"] "; 
                                    if(rss.author !== null && !_.isUndefined(rss.categories[0])) {
                                        rString += "[Post by "+rss.author+" in "+rss.categories[0]+"] ";
                                    }
                                    rString += "- "+rss.link;
                                    dbot.say(feed.server,feed.channel, rString);
                                    console.log("RSS: Url shortener request returned error statuscode "+response.statusCode+": "+body.error.message);
                                }
                            });

                            if(self.titleCache.length > 30) {
                                self.titleCache.splice(0, 1); 
                            }
                            self.titleCache.push(rss.title);
                        }
                    }
                }
            });
            feedparser.on('end', function() {
                feed.lastPosted = feed.newTime;
                dbot.db.feeds[fid] = feed;
            });
        }.bind(this),

        'checkFeeds': function() {
            console.log("Checking feeds...");
            if(dbot.db.feeds == null) {
                console.log("No active feeds...");
                return;
            }
            for(var i=0;i<dbot.db.feeds.length;++i) {
                this.internalAPI.makeRequest(i,dbot.db.feeds[i]);
            }
        }.bind(this),

        'reloadFeeds': function() {
            return setInterval(this.internalAPI.checkFeeds, this.pollInterval);
        }.bind(this)
    };

    this.commands = {
        '~addrssfeed': function(event) {
            if(event.params.length < 3) {
                event.reply("GIMME TWO PARAMETERS DUDE");
                return;
            }
            var now = Date.now();
            if(dbot.db.feeds == null)
                dbot.db.feeds = [];
            dbot.db.feeds.push({server:event.server, channel:event.channel.name, name:event.params[1], url:event.params[2], lastPosted: 0, newTime: 0});
            event.reply("Adding RSS feed named "+event.params[1]+" with URL "+event.params[2]);
        },

        '~rsstest': function(event) {
            event.reply("I posted RSS last @ "+this.lastPosted);
            event.reply("Checking feeds manually...");
            this.internalAPI.checkFeeds();
            event.reply("Call got through!");
        },

        '~delrssfeed': function(event) {
            for(var i=0;i<dbot.db.feeds.length;++i) {
                if(dbot.db.feeds[i].server == event.server && dbot.db.feeds[i].channel == event.channel.name && dbot.db.feeds[i].name == event.params[1]) {
                    dbot.db.feeds.splice(i, 1);
                    event.reply("Removed feed "+event.params[1]+" you were looking for...");
                    break;
                }
            }
        }
    };

    this.onLoad = function() {
        this.interval = this.internalAPI.reloadFeeds();
    };

    this.onDestroy = function() {
        clearInterval(this.interval);
    };
};

exports.fetch = function(dbot) {
    return new rss(dbot);
};