var express = require('express'),
	WebServer = express(),
	server = require('http').createServer(WebServer),
	RedisStore = require('connect-redis')(express),
	path = require('path'),
	redis = require('redis'),
	redisServer = redis.createClient(global.config.redis.port, global.config.redis.host),
	marked = require('marked'),
	utils = require('../public/src/utils.js'),
	fs = require('fs'),
	
	user = require('./user.js'),
	categories = require('./categories.js'),
	posts = require('./posts.js'),
	topics = require('./topics.js'),
	notifications = require('./notifications.js'),
	admin = require('./routes/admin.js'),
	userRoute = require('./routes/user.js'),
	installRoute = require('./routes/install.js'),
	auth = require('./routes/authentication.js'),
	meta = require('./meta.js');
(function(app) {
	var templates = null;
	
	app.build_header = function(res) {
		return templates['header'].parse({
			cssSrc: global.config['theme:src'] || '/vendor/bootstrap/css/bootstrap.min.css',
			title: global.config['title'] || 'NodeBB',
			csrf:res.locals.csrf_token
		});
	};
	// Middlewares
	app.use(express.favicon(path.join(__dirname, '../', 'public', 'favicon.ico')));
	app.use(require('less-middleware')({ src: path.join(__dirname, '../', 'public') }));
	app.use(express.static(path.join(__dirname, '../', 'public')));
	app.use(express.bodyParser());	// Puts POST vars in request.body
	app.use(express.cookieParser());	// If you want to parse cookies (res.cookies)
	app.use(express.compress());
	app.use(express.session({
		store: new RedisStore({
			client: redisServer,
			ttl: 60*60*24*14
		}),
		secret: global.config.secret,
		key: 'express.sid'
	}));
	app.use(express.csrf());
	app.use(function(req, res, next) {
		res.locals.csrf_token = req.session._csrf;
		next();
	});
	module.exports.init = function() {
		templates = global.templates;
	}
	auth.initialize(app);
	app.use(function(req, res, next) {
		// Don't bother with session handling for API requests
		if (/^\/api\//.test(req.url)) return next();
		if (req.user && req.user.uid) {
			user.session_ping(req.sessionID, req.user.uid);
		}
		// (Re-)register the session as active
		user.active.register(req.sessionID);
		next();
	});
	
	auth.create_routes(app);
	admin.create_routes(app);
	userRoute.create_routes(app);
	installRoute.create_routes(app);
	app.create_route = function(url, tpl) { // to remove
		return '';
	};
	// Basic Routes (entirely client-side parsed, goal is to move the rest of the crap in this file into this one section)
	(function() {
		var routes = ['login', 'register', 'account', 'recent', 'popular', 'active', '403', '404'];
		for (var i=0, ii=routes.length; i 0)) {
						
						user.getUserField(req.user.uid, 'userslug', function(userslug) {
							res.redirect('/users/'+userslug);							
						});
						return;
					}
					
					res.send(app.build_header(res) + app.create_route(route) + templates['footer']);
				});
			}(routes[i]));
		}
	}());
	
	// Complex Routes
	app.get('/', function(req, res) {
		categories.getAllCategories(function(returnData) {
			res.send(
				app.build_header(res) +
				'\n\t' +
				app.create_route('') +
				templates['footer']
			);
		}, 0);
	});
	app.get('/topic/:topic_id/:slug?', function(req, res) {
		var tid = req.params.topic_id;
		if (tid.match('.rss')) {
			fs.readFile('feeds/topics/' + tid, function (err, data) {
				if (err) {
					res.send("Unable to locate an rss feed at this location.");
					return;
				}
				
				res.setHeader('Content-Type', 'application/xml');
				res.setHeader('Content-Length', data.length);
				res.end(data);
			});
			return;
		}
		var topic_url = tid + (req.params.slug ? '/' + req.params.slug : '');
		topics.getTopicWithPosts(tid, ((req.user) ? req.user.uid : 0), function(topic) {
			res.send(
				app.build_header(res) +
				'\n\t' +
				'\n\t' +
				templates['footer']
			);
		});
	});
	app.get('/category/:category_id/:slug?', function(req, res) {
		var cid = req.params.category_id;
		if (cid.match('.rss')) {
			fs.readFile('feeds/categories/' + cid, function (err, data) {
				if (err) {
					res.send("Unable to locate an rss feed at this location.");
					return;
				}
				res.setHeader('Content-Type', 'application/xml');
				res.setHeader('Content-Length', data.length);
				res.end(data);
			});
			return;
		}
		var category_url = cid + (req.params.slug ? '/' + req.params.slug : '');
		categories.getCategoryById(cid, 0, function(returnData) {
			res.send(
				app.build_header(res) +
				'\n\t' +
				'\n\t' +
				templates['footer']
			);
		});
	});
	app.get('/confirm/:code', function(req, res) {
		res.send(app.build_header(res) + '' + templates['footer']);
	});
	
	// These functions are called via ajax once the initial page is loaded to populate templates with data
	function api_method(req, res) {
		var uid = (req.user) ? req.user.uid : 0;
		
		switch(req.params.method) {
			case 'get_templates_listing' :
					utils.walk(global.configuration.ROOT_DIRECTORY + '/public/templates', function(err, data) {
						res.json(data);
					});
				break;
			case 'home' :
					categories.getAllCategories(function(data) {
						data.motd_class = (config.show_motd === '1' || config.show_motd === undefined) ? '' : 'none';
						data.motd = marked(config.motd || "# NodeBB v0.1\nWelcome to NodeBB, the discussion platform of the future.\n\n Get NodeBB  Fork us on Github  @dcplabs");
						res.json(data);
					}, uid);
				break;
			case 'login' :
					var data = {},
						login_strategies = auth.get_login_strategies(),
						num_strategies = login_strategies.length;
					if (num_strategies == 0) {
						data = {
							'login_window:spansize': 'span12',
							'alternate_logins:display': 'none'
						};	
					} else {
						data = {
							'login_window:spansize': 'span6',
							'alternate_logins:display': 'block'
						}
						for (var i=0, ii=num_strategies; i