var ldap = require('ldapjs');

var server = ldap.createServer();

var checkPassword = null;
var errorCallback = null;
var warningCallback = null;
var ldapServerPassword = "asdg";
var serverPort = 389;

var cids = {};

module.exports = {
	init : function(options) {
		if(options["ldapServerPassword"]) {
			ldapServerPassword = options["ldapServerPassword"];
		} else {
			console.log("Warning: LdapAuth Serverpassword not defined!");
		}

		if(options["checkPassword"]) {
			checkPassword = options["checkPassword"];
		} else {
			console.log("Error: LdapAuth checkPassword function not defined! Auth will not work!");
		}

		if(options["serverPort"]) {
			serverPort = options["serverPort"];
		}

		if(options["warningCallback"]) {
			warningCallback = options["warningCallback"];
		}

		if(options["errorCallback"]) {
			errorCallback = options["errorCallback"];
		}

		loadServer();
	}
}

function loadServer() {
	//1. First connection and login to ldap Server
	server.bind('cn=auth', function(req, res, next) {
		if (req.dn.toString() !== 'cn=auth' || req.credentials !== ldapServerPassword) {
			if(warningCallback) {
				warningCallback("Someone with invaild ldapServerPassword wants to login.")
			}
			return next(new ldap.InvalidCredentialsError());
		}

		res.end();
		return next();
	});

	//2. Searching for user (We just save it for now and return a success)
	server.search('ou=user', function(req, res, next) {
		var cId = req["connection"]["ldap"]["id"];
		if(!req["filter"] || !req["filter"]["filters"] || !req["filter"]["filters"][0] || !req["filter"]["filters"][0]["raw"]) {
			if(errorCallback) {
				errorCallback("Invaild filterParameters...!");
			}
			return next(new ldap.InvalidCredentialsError());
		}
		var userName = req["filter"]["filters"][0]["raw"].toString();
		cids[cId] = userName;

		var dn = req.dn.toString();
		var obj = {
			dn: 'cn=auth, ou=user',
			status : 0, //Success
			attributes: {
				"cn" : "user",
				status:0,
				"username" : userName.split("@")[0],
				"mail" : userName
			}
		}
		res.send(obj);
		res.end();
		return next();
	});

	//3. Getting password. Then check user an password combination...
	server.bind('ou=user', function(req, res, next) {
		var dn = req.dn.toString();
		var cId = req["connection"]["ldap"]["id"];
		var userPassword = req["credentials"];
		var userName = cids[cId];

		//console.log("userName:",userName);
		//console.log("userPassword:",userPassword);
		delete cids[cId];
		if(checkPassword) {
			checkPassword({"userName" : userName, "userPassword": userPassword}, function(isCorrectPw) {
				if(isCorrectPw) {
					console.log("Vaild LOGIN")
					return res.end();
				} else {
					return next(new ldap.InvalidCredentialsError());
				}
			});
		} else {
			return next(new ldap.InvalidCredentialsError());
		}
	});

	server.listen(serverPort, function() {
	  console.log('Ldap Auth Server listening at ' + server.url);
	});
}