/**
 * ldap endpoint/http requests
 *
 */
(function () {
	'use strict';

	angular.module('cla.ldap.connections')
		.service('ldapResources', resources);

	resources.$inject = ['$resource', '$q'];

	/**
	 *
	 * @param $resource
	 */
	function resources($resource, $q) {
		var service = {
			endpoint: '/admin/system/ldap/act',
			resource: null,
			payload: {
				action: '',
				data: { },
				connection: { }
			},

			connectionTest: test,
			validate: validate,
			fetchAttributes: fetch,
			search: search,
			save: save
		};

		service.resource = resource();
		return service;

		/**
		 * test ldap connection
		 * @param connectionObject
		 * @return {{$promise}}
		 */
		function test(connectionObject) {
			// set up payload
			var payload = angular.copy(service.payload);
			payload.action = 'connect';
			delete payload.data;
			payload.connection = connectionObject;

			// send
			return service.resource.post(payload);
		}

		/**
		 * validate user groups or ous
		 * @param connectionObject
		 * @param directoryObject
		 * @return {{$promise}}
		 */
		function validate(connectionObject, directoryObject) {
			// set up payload
			var payload = angular.copy(service.payload);
			payload.action = 'groups';
			payload.data = directoryObject;
			payload.connection = connectionObject;

			// send
			return service.resource.post(payload);
		}

		/**
		 * fetches ldap attributes for a user
		 * @param connectionObject
		 * @param directoryObject
		 * @param attributesObject
		 * @returns {{$promise}}
		 */
		function fetch(connectionObject, directoryObject, attributesObject) {
			// set up payload
			var payload = angular.copy(service.payload);
			payload.action = 'attributes';
			payload.data = angular.merge(attributesObject, directoryObject);
			payload.connection = connectionObject;

			// send
			return service.resource.post(payload);
		}

		/**
		 * runs a custom ldap query
		 * @param connectionObject
		 * @param searchObject
		 * @returns {{$promise}}
		 */
		function search(connectionObject, searchObject) {
			// set up payload
			var payload = angular.copy(service.payload);
			payload.action = 'search';
			payload.data = searchObject;
			payload.connection = connectionObject;

			// send
			return service.resource.post(payload);
		}

		/**
		 * save the ldap connection
		 * @param connectionObject
		 * @param directoryObject
		 * @param attributesObject
		 * @param groupMapObject
		 * @param statusObject
		 * @param id
		 * @returns {{$promise}}
		 */
		function save(connectionObject, directoryObject, attributesObject, groupMapObject, statusObject, id) {
			// run some validation, validate will test connection and directory
			validate(connectionObject, directoryObject).$promise.then(function(response){
				if (response.success === false)
				{
					// open accordions for connection and directory
					$('#collapse-connection').collapse('show');
					$('#collapseTwo').collapse('show');
				}
			});

			// set up payload
			var payload = angular.copy(service.payload);
			payload.action = 'save';
			payload.data = angular.merge(attributesObject, directoryObject, groupMapObject, statusObject);
			payload.connection = connectionObject;

			payload.data['id'] = id;

			// send
			return service.resource.post(payload);
		}

		/**
		 * returns the resource object
		 */
		function resource() {
			return $resource('', {}, {
				post: { method: 'post', url: service.endpoint }
			});
		}

		/**
		 * a mock promise
		 */
		function mock(reject) {
			var defer = $q.defer();

			if (reject) {
				defer.reject({});
			} else {
				defer.resolve({});
			}

			return { $promise: defer.promise };
		}
	}
}());
