'use strict';

var q = require('q');
var logger = require('../../../utils/Logger').loggers.get('db');
var couchbase = require('couchbase');
var dbConfig = require('../DatabaseConfig');


var connectedBuckets = {};

var getConfig = function(connectionName){
    return dbConfig.getDataServicesConfig(connectionName);
};

var validateAuth = function(couchbaseConfig) {
	var deferred = q.defer();

	var bucketName = couchbaseConfig.bucket;
	var cbCluster = getCBCluster(couchbaseConfig);

	var manager = cbCluster.manager(couchbaseConfig.userName, couchbaseConfig.password);
    cbCluster.authenticate(couchbaseConfig.userName, couchbaseConfig.password);
	manager.listBuckets(function (err, buckets) {
		if (buckets) {
			var bucketFound = false;

			for (var i = 0; i < buckets.length; i++) {
				if (buckets[i].name === bucketName) {
					bucketFound = true;
					break;
				}
			}

			if (bucketFound) {
				deferred.resolve("Connected to Couchbase database");
			} else {
				deferred.reject(new Error("Couchbase Authentication Failed - Unable to " +
					"find bucket: " + bucketName + "!"));
			}
		} else {
			deferred.reject(new Error("Couchbase Authentication Failed - No Buckets returned!"));
		}
	});


	return deferred.promise;
};

function getCBCluster(conf) {
	const cluster =  new couchbase.Cluster(conf.host);
    cluster.authenticate(conf.userName, conf.password);
    return cluster;
};

module.exports = {
	initialise: function(connectionName, cbCloseCallBack) {
		logger.info('Invoke initialise function in CouchbaseDataService');
		var deferred = q.defer();
        connectionName = dbConfig.validateConnectionName(connectionName);
		var couchbaseConfig = dbConfig.getDataServicesConfig(connectionName);
		var bucketName = couchbaseConfig.bucket;
		var cbCluster = getCBCluster(couchbaseConfig);

		if (couchbaseConfig.userName && couchbaseConfig.password) {
			validateAuth(couchbaseConfig).then(function success(msg) {
                connectedBuckets[connectionName] = cbCluster.openBucket(bucketName);
				deferred.resolve(msg);
			}, function error(err) {
				logger.error(err);
				deferred.reject(err);
			});
		} else {
			connectedBuckets[connectionName] = cbCluster.openBucket(bucketName);

			var msg = "Connected to Couchbase database";
			logger.info(msg);
			deferred.resolve(msg);
		}


		return deferred.promise;
	},

	close: function(connectionName) {
		logger.info('Invoke close function in CouchbaseDataService');
		var deferred = q.defer();
        connectionName = dbConfig.validateConnectionName(connectionName);
		if (connectedBuckets[connectionName] && connectedBuckets[connectionName].connected) {
            connectedBuckets[connectionName].disconnect();
            delete connectedBuckets[connectionName];
		}

		deferred.resolve();

		return deferred.promise;
	},
	getBucket: function(connectionName) {
        connectionName = dbConfig.validateConnectionName(connectionName);
		return connectedBuckets[connectionName];
	},
	validateAuth: validateAuth,

    getConfig: getConfig
};
