(function() {
	'use strict';

	angular.module('uniflash').service('ufTargetSetupSrv', ufTargetSetupSrv);

	ufTargetSetupSrv.$inject = ['$rootScope', '$state', '$stateParams', '$q', '$log', 'ticFileStorage', 'ufAgentInstallDialog', 'ufSettingsSrv', 'ticAlerts', 'ufPreferencesSrv'];

	function ufTargetSetupSrv($rootScope, $state, $stateParams, $q, $log, ticFileStorage, ufAgentInstallDialog, ufSettingsSrv, ticAlerts, ufPreferencesSrv) {
		let deviceFilter: string = '';
		let deviceCategoryFilter: string = 'All';
		let isDeviceEntryExpanded = false;
		let selectedDevice = '';
		let selectedConnection = '';
		let setConnectionIndex = -1;
		let deviceSelected = false;
		let hideDeviceSelectionOptions = false;
		let hideConnectionSelectionOptions = false;
		let lpSelected = false;
		let started = false;
        let deviceDetector = null;
		let deviceDetectorCreated = false;
		let detectedDeviceList = null;
		let detectingDevices = false;
		let newestDetected = 0;
		let trackNew = false;
		let detectStarted = false;
		let detectDownloading = false;
		let detectDownloadPercent = 0;
		let missingTICloudAgent = false;
		let identifiedDevice = [];
		let detectDeviceStarted = 0;
		let dialogInstance = null;

		function toggleShowDetectWelcomePage() {
			const newShowWelcomePageSetting = !ufPreferencesSrv.get('showDetectWelcomePage');
			ufPreferencesSrv.set('showDetectWelcomePage', newShowWelcomePageSetting);

			if ( !newShowWelcomePageSetting && ufSettingsSrv.autoTargetDetectionSelectValue === 'Auto' ) {
				this.startDetection();	// start detection if welcome page dismissed
			}
		}
		
        function reset() {
           this.deviceFilter = '';
           this.deviceCategoryFilter = 'All';
           this.selectedDevice = '';
		   this.selectedConnection = '';
		   this.deviceSelected = false;
		   this.hideDeviceSelectionOptions = false;
		   this.hideConnectionSelectionOptions = false;
		   this.lpSelected = false;
		   this.started = false;
		   this.setConnectionIndex = -1;
		}
        
		function handleError(e) {
			if ( e.message ) {
				$log.debug('ufTargetSetupSrv error: ' + e.message);
			} else {
				$log.debug('ufTargetSetupSrv error: ' + JSON.stringify(e));
			}
		}

		function logProbes() {

			let curDetectedDeviceList = [];
			identifiedDevice = [];
			detectDeviceStarted = 0;
			return deviceDetector.detectDebugProbes()
				.then(function(data) {

					return $q.all(data.probes.map(function(probe) {
						return deviceDetector.detectDeviceWithProbe(probe)
						.then(function(result) {
							let deviceXml = result.deviceXml;
							let deviceName = result.name;

							// special handling for MSP430 detection
							if ( probe.connectionXml.indexOf('TIMSP430') > -1 ) {
								deviceXml = result.name;

								if ( deviceXml === "MSP430FR2310" ||
									deviceXml === "MSP430FR2311" ||
									deviceXml === "MSP430FR5962" ||
									deviceXml === "MSP430FR5964" )
								{
									deviceXml = deviceXml.toLowerCase();
								} else if ( deviceXml.indexOf('x') > -1 ) {
									deviceName = 'Unable to determine exact device [' + deviceName + ']';
								}
							}
							
							curDetectedDeviceList.push({
								'id': probe.id,
								'connectionXml' : probe.connectionXml, 
								'deviceName' : deviceName, 
								'deviceXml' : deviceXml, 
								'serial' : probe.serialNumber, 
								'overrides': probe.overrides
							});
							if ( trackNew ) { newestDetected = probe.id; }
						})
						.catch(handleError);
					}));
				}).finally(() => {
					detectedDeviceList = curDetectedDeviceList;
				})
				.catch(handleError);
		}

		function startDetection() {
			if (!ufPreferencesSrv.get('showDetectWelcomePage')) {
				try {
					if ( deviceDetector ) {
						startDetectionInternal();
					} else {
						missingTICloudAgent = false;
						TICloudAgent.Init()
							.then(function(newAgent) {
								// get event broker module and fetch data and add listener
								return newAgent.getSubModule("DeviceDetector");
							})
							.then(function(newModule) {
								deviceDetector = newModule;
								deviceDetectorCreated = true;
								startDetectionInternal();
							})
							.catch((error) => {
								if (error instanceof Array) {
									missingTICloudAgent = true;
									// cloud agent installation error
									let params = {
										errors: error
									};
									// try to handle the installation issues
									return TICloudAgent.Install.getInstallWizard(params)
										.then((installWizardObj) => {
											return ufAgentInstallDialog.show(installWizardObj);
										});
								} else {
									// we can't handle it here, so keep it going up
									throw error;
								}
							});
					}
				} catch(e) {
					//alert("caught: " + e);
				}
			}
		}
		
		function startDetectionInternal() {
			detectedDeviceList = [];
			deviceDetector.addListener("progress", function(data) {
				if ( data.isFirstUpdate ) {
					detectDownloading = true;
				} else if ( data.isComplete ) {
					detectDownloading = false;
					detectDownloadPercent = 0;
				}
				if ( data.percent ) {
					detectDownloadPercent = data.percent;
				}
			});
			deviceDetector.addListener("attach", function(data) {
				detectingDevices = true;
				trackNew = true;
				logProbes().then(function() {
					detectingDevices = false;
				});		
			});
			deviceDetector.addListener("detach", function(data) {
				detectingDevices = true;
				trackNew = false;
				logProbes().then(function() {
					detectingDevices = false;	
				});		
			});
			trackNew = false;
			detectingDevices = true;
			detectStarted = true;
			detectDownloading = false;
			detectDownloadPercent = 0;
			logProbes().then(function() {
				detectingDevices = false;
				
				if ( ufSettingsSrv.autoTargetDetectionSelectValue === 'Manual' ) {
					closeDeviceDetector();
				}
			});
		}
		
		function detectDownloadingStatus() {
			return detectDownloading;
		}
		
		function detectDownloadPercentStatus() {
			return detectDownloadPercent;
		}
		
		function detectStartedStatus() {
			return detectStarted;
		}
		
		function missingTICloudAgentStatus() {
			return missingTICloudAgent;
		}
		
		function getDetectedDeviceList() {
			return detectedDeviceList;	
		}

		function resetDetectedDeviceList() {
			detectedDeviceList = [];	
		}
		
		function getDetectingStatus() {
			return detectingDevices;
		}
		
		function setDetectingStatus(value) {
			return detectingDevices = value;
		}
		
		function getTrackNewStatus() {
			return trackNew;
		}
		
		function getNewestDetected() {
			return newestDetected;
		}
		
		function getDeviceDetectorCreated() {
			return deviceDetectorCreated;
		}
		
		// need to shut down the detector when not on the setup page
		function closeDeviceDetector() {
			try {
				if ( deviceDetector ) {
					deviceDetector.close()
						.then(function() {
							deviceDetector = null;
						})
						.catch(handleError);
				}
			} catch(e) {
				//alert("caught: " + e);
			}
		}
		
		function autoTargetDetectionSelectValueChanged() {
			let jsonStr = JSON.stringify({'autoTargetDetectionSelectValue':ufSettingsSrv.autoTargetDetectionSelectValue});			
			ticFileStorage.saveFile('ufSettings', jsonStr);
			
			if ( ufSettingsSrv.autoTargetDetectionSelectValue === 'Auto' ) {
				this.startDetection();
			} else {
				this.closeDeviceDetector();
			}
		}

		function getIdentifiedDeviceList(index) {
			return identifiedDevice;
		}

		function getIdentifiedDevice(index) {
			return identifiedDevice[index];
		}

		function getDetectDeviceStarted() {
			return detectDeviceStarted;
		}

		function setDetectDeviceStarted(value) {
			detectDeviceStarted = value;
		}

		$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
			if (toState.templateUrl !== 'welcome.html' && deviceDetector) {
				// moving away from the setup page, close the device detector
				closeDeviceDetector();
			}

		});
		
		return {
			reset : reset,
			deviceFilter : deviceFilter,
            deviceCategoryFilter : deviceCategoryFilter,
			isDeviceEntryExpanded : isDeviceEntryExpanded,
            selectedDevice : selectedDevice,
			selectedConnection : selectedConnection,
			setConnectionIndex : setConnectionIndex,
			deviceSelected : deviceSelected,
			hideDeviceSelectionOptions : hideDeviceSelectionOptions,
			hideConnectionSelectionOptions : hideConnectionSelectionOptions,
			lpSelected : lpSelected,
			started : started,
			getDetectedDeviceList : getDetectedDeviceList,
			resetDetectedDeviceList : resetDetectedDeviceList,
			getDetectingStatus : getDetectingStatus,
			setDetectingStatus : setDetectingStatus,
			getTrackNewStatus : getTrackNewStatus,
			getNewestDetected : getNewestDetected,
			detectStartedStatus : detectStartedStatus,
			startDetection : startDetection,
			closeDeviceDetector : closeDeviceDetector,
			autoTargetDetectionSelectValueChanged : autoTargetDetectionSelectValueChanged,
			getDeviceDetectorCreated : getDeviceDetectorCreated,
			detectDownloadingStatus : detectDownloadingStatus,
			detectDownloadPercentStatus : detectDownloadPercentStatus,
			missingTICloudAgentStatus : missingTICloudAgentStatus,
			getIdentifiedDeviceList: getIdentifiedDeviceList,
			getIdentifiedDevice: getIdentifiedDevice,
			getDetectDeviceStarted: getDetectDeviceStarted,
			setDetectDeviceStarted: setDetectDeviceStarted,
			toggleShowDetectWelcomePage: toggleShowDetectWelcomePage
		};
	}

})();
