var myApp = angular.module('myApp');

myApp.controller('AppsController', ['$scope', '$http', '$location', '$routeParams', '$window', function($scope, $http, $location, $routeParams, $window){
	console.log('AppsController loaded...');

	$scope.app = {};

	$scope.privacyRisksTC = [];
	$scope.securityRisksTC = [];
	$scope.appResultList = new Array(200);
	$scope.reputationHTI = false;
	$scope.spHTI = false;
	$scope.finalHTI = false;

	$scope.getApps = function(){

		angular.element('*[id^="tviz"]').remove();

		var genre = $routeParams.genre;
		var query = "";
		if(genre) {
			query += "/?genre=" + genre;
		}
		$http.get('/crawler/downloadedapps' + query).then(function(response){
			$scope.apps = response.data;
		});
	}

	$scope.getApp = function(){

		angular.element('*[id^="tviz"]').remove();

		var id = $routeParams.id;
		var posture = $routeParams.posture;
		var query = "";
		if(posture) {
			query += "/?posture=" + posture;
		}
		$http.get('/crawler/downloadedapps/'+id+query).then(function(response){
			$scope.app = response.data;
			//showCT($scope.app);
			$scope.privacyRisksTC = [
				"Client communication used?",
				"SSL/TLS used?",
				"Domains accessed with http AND https: ",
				"Custom SSL/TLS trust manager implemented?",
				"Faulty custom SSL/TLS trust manager implemented?",
				"SSL/TLS using custom error handling?",
				"SSL/TLS using faulty custom error handling?",
				"SSL/TLS using manual domain name verification?",
				"Unprotected communication?",
				"Unprotected HTML?",
				"Cryptographic Primitives: ",
				"Application needs dangerous permissions? ",
				"JavaScript to SDK API bridge usage?",
				"Is application overprivileged?",
				"Userdefined permission usage: ",
				"WiFi-Direct enabled?",
				"App can handle documents of mimeType: ",
				"Screenshot protection used?",
				"Tap Jacking Protection used?",
				//"",
				"Scheduled Alarm Manager registered?",
				"Dynamically loaded code at runtime?",
				"Allow app debugging Flag?",
				"Allow autoexecute after Phone Reboot?",
				//"",
				"App uses outdated signature key?",
				"Contains native libraries: "
			];
			$scope.securityRisksTC = [
				"Obfuscation used?",
				"Device administration policy entries: ",
				"Accessed unique identifier(s): ",
				"Advertisment-/tracking frameworks found: ",
				"App provides public accessible activities?",
				"Backup of app is allowed?",
				"Log Statement Enabled?",
				"Permission to access address book?",
				//"",
				"Unprotected preference files found?"
			];
		});
	}

	$scope.getApp2 = function(app, $index){
		angular.element('*[id^="tviz"]').remove();
		if(app.reviews.length && app.permissions.length) {
			$http.get('/crawler/downloadedapps/'+app.appId).then(function(response) {
				//$scope.app = response.data;
				$scope.appResultList[$index] = response.data;
				//$scope.showTviz(response.data, $index);
				$scope.securityRisksTC = [		
					"Client communication used?",
					"SSL/TLS used?",
					"Domains accessed with http AND https: ",
					"Custom SSL/TLS trust manager implemented?",
					"Faulty custom SSL/TLS trust manager implemented?",
					"SSL/TLS using custom error handling?",
					"SSL/TLS using faulty custom error handling?",
					"SSL/TLS using manual domain name verification?",
					"Unprotected communication?",
					"Unprotected HTML?",
					"Cryptographic Primitives: ",
					"Application needs dangerous permissions? ",
					"JavaScript to SDK API bridge usage?",
					"Is application overprivileged?",
					"Userdefined permission usage: ",
					"WiFi-Direct enabled?",
					"App can handle documents of mimeType: ",
					"Screenshot protection used?",
					"Tap Jacking Protection used?",
					//"",
					"Scheduled Alarm Manager registered?",
					"Dynamically loaded code at runtime?",
					"Allow app debugging Flag?",
					"Allow autoexecute after Phone Reboot?",
					//"",
					"App uses outdated signature key?",
					"Contains native libraries: "
				];
				$scope.privacyRisksTC = [
					"Obfuscation used?",
					"Device administration policy entries: ",
					"Accessed unique identifier(s): ",
					"Advertisment-/tracking frameworks found: ",
					"App provides public accessible activities?",
					"Backup of app is allowed?",
					"Log Statement Enabled?",
					"Permission to access address book?",
					//"",
					"Unprotected preference files found?"
				];
			});
		}
		
	}

	$scope.getSPResult = function(testName) {
		var testCases = $scope.app.appicaptor.indicator;
		var indicator = _.filter(testCases, function(testCase) { 
			return testCase.attr.text == testName; 
		})[0];
		return indicator ? indicator.attr.value : "";
	}

	$scope.getRatingsTCF = function(app) {
		var output = "(";
		output += Number(app.averageRatingTrustValue.toFixed(2)) + ",";
		output += Number(app.averageRatingConfidenceValue.toFixed(2)) + ",";
		output += "NA" + ")";
		return output;
	}
	$scope.getReviewsTCF = function(app) {
		var output = "(";
		output += Number(app.reviewsTrustValue.toFixed(2)) + ",";
		output += Number(app.reviewsConfidenceValue.toFixed(2)) + ",";
		output += "NA" + ")";
		return output;
	}

	$scope.getPermissionsTCF = function(app) {
		var output = "(";
		output += Number(app.permissionsTrustValue.toFixed(2)) + ",";
		output += Number(app.cofidenceInNumberofPermissions.toFixed(2)) + ",";
		output += "NA" + ")";
		return output;
	}

	$scope.getSecurityRisksTCF = function(app) {
		var output = "(";
		output += Number(app.sTrustValue.toFixed(2)) + ",";
		output += Number(app.sConfidenceValue.toFixed(2)) + ",";
		output += "NA" + ")";
		return output;
	}

	$scope.getPrivacyRisksTCF = function(app) {
		var output = "(";
		output += Number(app.pTrustValue.toFixed(2)) + ",";
		output += Number(app.pConfidenceValue.toFixed(2)) + ",";
		output += "NA" + ")";
		return output;
	}

	$scope.getTrustPlusFrameworkScore = function(app) {
		var weight = 1/3;
		var ratingMetric = (app.score-1)/4;
		var score = (weight*ratingMetric*app.averageRatingConfidenceValue) + (weight*app.reviewMetric*app.reviewsConfidenceValue);

		return Number(score.toFixed(2));
	}

	$scope.$watch('app', function (newValue, oldValue, scope) {
		if(newValue.appId) {
			$scope.showCertainTrust();			
		}
	});

	$scope.showCategoryCertainTrust = function () { //this will just calculate the expectation of the Reputaion and SP QUality category considering the sub categories
		var f = 0.0;
		var CT_objects = [];
		var CT_names = ['ratingsCT', 'reviewsCT', 'permissionsCT', 'reputationAndResult', 'securityRisksCT', 'privacyRisksCT', 'spQualityAndResult'];
		var ANDObserver = {
			update: function () {
				// calculate the CertainTrust.AND for both values
				var CT_result = CT_objects['ratingsCT'].AND(CT_objects['reviewsCT']).AND(CT_objects['permissionsCT']);

				// update the HTI which displays the result
				CT_objects['reputationAndResult'].setF(CT_result.getF());
				CT_objects['reputationAndResult'].setTC(CT_result.getT(), CT_result.getC());
			}
		};

		var app = $scope.app;

		for (var i = 0, element; element = CT_names[i]; ++i) {
			var CT_object;

			if (-1 !== element.indexOf('ratings')) {
				CT_object = new CertainTrust(Number(app.averageRatingTrustValue.toFixed(2)), Number(app.averageRatingConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('reviews')) {
				CT_object = new CertainTrust(Number(app.reviewsTrustValue.toFixed(2)), Number(app.reviewsConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('permissions')) {
				CT_object = new CertainTrust(Number(app.permissionsTrustValue.toFixed(2)), Number(app.cofidenceInNumberofPermissions.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('security')) {
				CT_object = new CertainTrust(Number(app.sTrustValue.toFixed(2)), Number(app.sConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('privacy')) {
				CT_object = new CertainTrust(Number(app.pTrustValue.toFixed(2)), Number(app.pConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('Result')) {
				CT_object = new CertainTrust(1, 1, 1, 3);
			}

			// the result HTIs should be read-only
			// var isResultHTI = (-1 !== element.indexOf('Result'));
			var HTI = new CertainTrustHTI(CT_object, { domParent: element, readonly: true });

			// register our observers for the calculation
			// if (!isResultHTI) {
			// 	CT_object.addObserver(ANDObserver);
			// }

			// store the created objects for easy access in the Arrays
			CT_objects[element] = CT_object;
		}
		// ANDObserver.update();

		// calculate the CertainTrust.AND for both values
		var repuatationCT_result = CT_objects['ratingsCT'].AND(CT_objects['reviewsCT']).AND(CT_objects['permissionsCT']);
		var spQualityCT_result = CT_objects['securityRisksCT'].AND(CT_objects['privacyRisksCT']);

		// update the HTI which displays the result
		CT_objects['reputationAndResult'].setF(repuatationCT_result.getF());
		CT_objects['reputationAndResult'].setTC(repuatationCT_result.getT(), repuatationCT_result.getC());

		CT_objects['spQualityAndResult'].setF(spQualityCT_result.getF());
		CT_objects['spQualityAndResult'].setTC(spQualityCT_result.getT(), spQualityCT_result.getC());

		f = 0.9;
		var wFusionArr = new Array();
		wFusionArr.push(CT_objects['ratingsCT']);
		wFusionArr.push(CT_objects['reviewsCT']);
		wFusionArr.push(CT_objects['permissionsCT']);

		var wFusionWeightArr = new Array();
		wFusionWeightArr.push(1);
		wFusionWeightArr.push(2);
		wFusionWeightArr.push(1);

		var repuatationWFusionCT_result = CT_objects['ratingsCT'].wFusion(wFusionArr,wFusionWeightArr);
		repuatationWFusionCT_result.setF(f);
		var HTI1 = new CertainTrustHTI(repuatationWFusionCT_result, { domParent: "reputationWFusionResult", readonly: true });

		var repuatationCFusionCT_result = CT_objects['ratingsCT'].cFusion(wFusionArr,wFusionWeightArr);
		var HTI11 = new CertainTrustHTI(repuatationCFusionCT_result, { domParent: "reputationCFusionResult", readonly: true });

		var wFusionSPArr = new Array();
		wFusionSPArr.push(CT_objects['securityRisksCT']);
		wFusionSPArr.push(CT_objects['privacyRisksCT']);

		var wFusionSPWeightArr = new Array();
		wFusionSPWeightArr.push(1);
		wFusionSPWeightArr.push(1);

		var spQualityWFusionCT_result = CT_objects['securityRisksCT'].wFusion(wFusionSPArr,wFusionSPWeightArr);
		spQualityWFusionCT_result.setF(f);
		var HTI2 = new CertainTrustHTI(spQualityWFusionCT_result, { domParent: "spQualityWFusionResult", readonly: true });
		
		var spQualityCFusionCT_result = CT_objects['securityRisksCT'].cFusion(wFusionSPArr,wFusionSPWeightArr);
		var HTI22 = new CertainTrustHTI(spQualityCFusionCT_result, { domParent: "spQualityCFusionResult", readonly: true });

		var finalAndCT_result = repuatationCT_result.AND(spQualityCT_result);
		var HTI3 = new CertainTrustHTI(finalAndCT_result, { domParent: "finalAndResult", readonly: true });

		var finalWFusionCT_result = repuatationWFusionCT_result.AND(spQualityWFusionCT_result);
		var HTI33 = new CertainTrustHTI(finalWFusionCT_result, { domParent: "finalWFusionResult", readonly: true });
		
		var finalCFusionCT_result = repuatationCFusionCT_result.AND(spQualityCFusionCT_result);
		var HTI333 = new CertainTrustHTI(finalCFusionCT_result, { domParent: "finalCFusionResult", readonly: true });
	}


	$scope.showCertainTrust = function () { //this will just calculate the expectation of the Reputaion and SP QUality category considering the sub categories
		var f = 0.0;
		var CT_objects = [];
		var CT_names = ['ratingsCT', 'reviewsCT', 'securityRisksCT', 'privacyRisksCT'];
		var ANDObserver = {
			update: function () {
				// calculate the CertainTrust.AND for both values
				var CT_result = CT_objects['ratingsCT'].AND(CT_objects['reviewsCT']).AND(CT_objects['permissionsCT']);

				// update the HTI which displays the result
				CT_objects['reputationAndResult'].setF(CT_result.getF());
				CT_objects['reputationAndResult'].setTC(CT_result.getT(), CT_result.getC());
			}
		};

		var app = $scope.app;

		for (var i = 0, element; element = CT_names[i]; ++i) {
			var CT_object;

			if (-1 !== element.indexOf('ratings')) {
				CT_object = new CertainTrust(Number(app.averageRatingTrustValue.toFixed(2)), Number(app.averageRatingConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('reviews')) {
				CT_object = new CertainTrust(Number(app.reviewsTrustValue.toFixed(2)), Number(app.reviewsConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('security')) {
				CT_object = new CertainTrust(Number(app.sTrustValue.toFixed(2)), Number(app.sConfidenceValue.toFixed(2)), f, 3);
			}
			if (-1 !== element.indexOf('privacy')) {
				CT_object = new CertainTrust(Number(app.pTrustValue.toFixed(2)), Number(app.pConfidenceValue.toFixed(2)), f, 3);
			}

			// the result HTIs should be read-only
			var HTI = new CertainTrustHTI(CT_object, { domParent: element, readonly: true });

			CT_objects[element] = CT_object;
		}
		// ANDObserver.update();

		f = 0.9;

		var spQualityCT_result = CT_objects['securityRisksCT'].AND(CT_objects['privacyRisksCT']);
		spQualityCT_result.setF(f);
		var HTI2 = new CertainTrustHTI(spQualityCT_result, { domParent: "spQualityAndResult", readonly: true });

		
		var wFusionArr = new Array();
		wFusionArr.push(CT_objects['ratingsCT']);
		wFusionArr.push(CT_objects['reviewsCT']);

		var wFusionWeightArr = new Array();
		wFusionWeightArr.push(1/3);
		wFusionWeightArr.push(2/3);

		var repuatationWFusionCT_result = CT_objects['ratingsCT'].wFusion(wFusionArr,wFusionWeightArr);
		repuatationWFusionCT_result.setF(f);
		var HTI1 = new CertainTrustHTI(repuatationWFusionCT_result, { domParent: "reputationWFusionResult", readonly: true });

		var finalAndCT_result = repuatationWFusionCT_result.AND(spQualityCT_result);
		var HTI3 = new CertainTrustHTI(finalAndCT_result, { domParent: "finalAndResult", readonly: true });

		var ct1 = new CertainTrust("Reputation",repuatationWFusionCT_result.getT(), repuatationWFusionCT_result.getC(),repuatationWFusionCT_result.getF(),3);
		var ct2 = new CertainTrust("S&p Quality",spQualityCT_result.getT(), spQualityCT_result.getC(),spQualityCT_result.getF(),3);
		new CertainTrustTViz([ct1,ct2], { id: "tvizAnd", middle: "AND",
			onClick: function(certainTrust) {
				if (certainTrust.getName() === "Reputation") $scope.reputationHTI = true;
				else $scope.spHTI = true;
				$scope.$apply();
			},
			onMiddleClick: function(certainTrust) {
				$scope.finalHTI = true;
				$scope.$apply();
			}
		});
		new CertainTrustTViz([ct1,ct2], { id: "tvizAverage", middle: "AVERAGE" });

	}

	$scope.showTviz = function(app, index) {

		var f = 0.0;

		var CT_Ratings = new CertainTrust(Number(app.averageRatingTrustValue.toFixed(2)), Number(app.averageRatingConfidenceValue.toFixed(2)), f, 3);
		var CT_Reviews = new CertainTrust(Number(app.reviewsTrustValue.toFixed(2)), Number(app.reviewsConfidenceValue.toFixed(2)), f, 3);

		var CT_Security = new CertainTrust(Number(app.sTrustValue.toFixed(2)), Number(app.sConfidenceValue.toFixed(2)), f, 3);
		var CT_Privacy = new CertainTrust(Number(app.pTrustValue.toFixed(2)), Number(app.pConfidenceValue.toFixed(2)), f, 3);

		f = 0.9;
		
		var spQualityCT_result = CT_Security.AND(CT_Privacy);
		spQualityCT_result.setF(f);
		
		var wFusionArr = new Array();
		wFusionArr.push(CT_Ratings);
		wFusionArr.push(CT_Reviews);

		var wFusionWeightArr = new Array();
		wFusionWeightArr.push(1/3);
		wFusionWeightArr.push(2/3);

		var repuatationWFusionCT_result = CT_Ratings.wFusion(wFusionArr,wFusionWeightArr);
		repuatationWFusionCT_result.setF(f);

		var tvizid = "tviz" + index;
		var ct1 = new CertainTrust("Reputation",repuatationWFusionCT_result.getT(), repuatationWFusionCT_result.getC(),repuatationWFusionCT_result.getF(),3);
		var ct2 = new CertainTrust("S&p Quality",spQualityCT_result.getT(), spQualityCT_result.getC(),spQualityCT_result.getF(),3);
		new CertainTrustTViz([ct1,ct2], { canvas: { height: 200, width: 200 }, id: tvizid, middle: "AND" });
	}
}]);