(function (Feed) {
	var db = require('./database'),
		posts = require('./posts'),
		topics = require('./topics'),
		categories = require('./categories'),

		fs = require('fs'),
		rss = require('rss'),
		winston = require('winston'),
		path = require('path'),
		nconf = require('nconf'),
		async = require('async');

	Feed.defaults = {
		ttl: 60,
		basePath: path.join(__dirname, '../', 'feeds'),
		baseUrl: nconf.get('url') + 'feeds'
	};

	Feed.saveFeed = function (location, feed, callback) {
		var savePath = path.join(__dirname, '../', location);

		fs.writeFile(savePath, feed.xml(), function (err) {
			if (err) return winston.err(err);

			if (callback) callback(err);
		});
	}

	Feed.updateTopic = function (tid, callback) {
		topics.getTopicWithPosts(tid, 0, 0, -1, true, function (err, topicData) {
			if (err) {
				if(callback) {
					return callback(new Error('topic-invalid'));
				} else {
					winston.error(err.message);
					return;
				}
			}

			var feed = new rss({
					title: topicData.topic_name,
					description: topicData.posts[0].content,
					feed_url: Feed.defaults.baseUrl + '/topics/' + tid + '.rss',
					site_url: nconf.get('url') + 'topic/' + topicData.slug,
					image_url: topicData.posts[0].picture,
					author: topicData.posts[0].username,
					ttl: Feed.defaults.ttl
				}),
				dateStamp;

			// Add pubDate if topic contains posts
			if (topicData.posts.length > 0) {
				feed.pubDate = new Date(parseInt(topicData.posts[0].timestamp, 10)).toUTCString();
			}

			async.each(topicData.posts, function(postData, next) {
				if (parseInt(postData.deleted, 10) === 0) {
					dateStamp = new Date(parseInt(parseInt(postData.edited, 10) === 0 ? postData.timestamp : postData.edited, 10)).toUTCString();

					feed.item({
						title: 'Reply to ' + topicData.topic_name + ' on ' + dateStamp,
						description: postData.content,
						url: nconf.get('url') + 'topic/' + topicData.slug + '#' + postData.pid,
						author: postData.username,
						date: dateStamp
					});
				}

				next();
			}, function() {
				Feed.saveFeed('feeds/topics/' + tid + '.rss', feed, function (err) {
					if (process.env.NODE_ENV === 'development') {
						winston.info('[rss] Re-generated RSS Feed for tid ' + tid + '.');
					}

					if (callback) {
						callback();
					}
				});
			});
		});

	};

	Feed.updateCategory = function (cid, callback) {
		categories.getCategoryById(cid, 0, function (err, categoryData) {
			if (err) return callback(new Error('category-invalid'));

			var feed = new rss({
					title: categoryData.category_name,
					description: categoryData.category_description,
					feed_url: Feed.defaults.baseUrl + '/categories/' + cid + '.rss',
					site_url: nconf.get('url') + 'category/' + categoryData.category_id,
					ttl: Feed.defaults.ttl
				});

			// Add pubDate if category has topics
			if (categoryData.topics.length > 0) feed.pubDate = new Date(parseInt(categoryData.topics[0].lastposttime, 10)).toUTCString();

			async.eachSeries(categoryData.topics, function(topicData, next) {
				feed.item({
					title: topicData.title,
					url: nconf.get('url') + 'topic/' + topicData.slug,
					author: topicData.username,
					date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
				});

				next();
			}, function() {
				Feed.saveFeed('feeds/categories/' + cid + '.rss', feed, function (err) {
					if (process.env.NODE_ENV === 'development') {
						winston.info('[rss] Re-generated RSS Feed for cid ' + cid + '.');
					}

					if (callback) {
						callback();
					}
				});
			});
		});
	};

	Feed.updateRecent = function(callback) {
		topics.getLatestTopics(0, 0, 19, undefined, function (err, recentData) {
			var	feed = new rss({
					title: 'Recently Active Topics',
					description: 'A list of topics that have been active within the past 24 hours',
					feed_url: Feed.defaults.baseUrl + '/recent.rss',
					site_url: nconf.get('url') + 'recent',
					ttl: Feed.defaults.ttl
				});

			// Add pubDate if recent topics list contains topics
			if (recentData.topics.length > 0) {
				feed.pubDate = new Date(parseInt(recentData.topics[0].lastposttime, 10)).toUTCString();
			}

			async.eachSeries(recentData.topics, function(topicData, next) {
				feed.item({
					title: topicData.title,
					url: nconf.get('url') + 'topic/' + topicData.slug,
					author: topicData.username,
					date: new Date(parseInt(topicData.lastposttime, 10)).toUTCString()
				});
				next();
			}, function() {
				Feed.saveFeed('feeds/recent.rss', feed, function (err) {
					if (process.env.NODE_ENV === 'development') {
						winston.info('[rss] Re-generated "recent posts" RSS Feed.');
					}

					if (callback) callback();
				});
			});
		});
	};
}(exports));