(function() {
	'use strict';

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

	ufAddOnTargetSrv.$inject = ['$window','ufTargetSetupSrv'];
	
	function ufAddOnTargetSrv($window,ufTargetSetupSrv) {
        var process;
		var deviceList = [{name:'CC3100 / CC3200',
						  family:'Wireless',
						  connection:'Serial(UART) Interface',
						  type:'addon',
						  subtype:'v3',
						  show:true,
						  link:'http://processors.wiki.ti.com/index.php/CCS_UniFlash_v3.4.1_Release_Notes#Installation_Instructions'},
						 {name:'CC31xx / CC32xx',
						  family:'Wireless',
						  connection:'Serial(UART) Interface',
						  type:'addon',
						  subtype:'button',
						  show:icSupported(),
						  moduleName:'Image Creator'}];
		var numFilteredDevices = 0;	
						  
		function getDeviceList() {
			if ( ufTargetSetupSrv.selectedConnection && !ufTargetSetupSrv.selectedDevice ) {
				return [];	// if connection is selected but device is not
			}
			var filteredDeviceList = _.filter(deviceList, showDevice);
			numFilteredDevices = filteredDeviceList.length;
			return filteredDeviceList;
		};
		
		function getNumFilteredDevices() {
			return numFilteredDevices;
		}
		
		function showDevice(device) {
			return ((device.name.toLowerCase().indexOf(ufTargetSetupSrv.deviceFilter.toLowerCase()) !== -1) && device.show &&
				    (ufTargetSetupSrv.deviceCategoryFilter === 'All' || ufTargetSetupSrv.deviceCategoryFilter === device.family));
		};
		
        function selectDevice(device) {
			ufTargetSetupSrv.selectedDevice = {id:device.name,type:device.type,subtype:device.subtype,link:device.link,moduleName:device.moduleName};
			ufTargetSetupSrv.selectedConnection = {id:device.connection};
			ufTargetSetupSrv.deviceSelected = true;
			ufTargetSetupSrv.lpSelected = false;
			ufTargetSetupSrv.hideDeviceSelectionOptions = true;
            ufTargetSetupSrv.hideConnectionSelectionOptions = true;
		};
		
		function handleAction() {
			if ( (ufTargetSetupSrv.selectedDevice.subtype==='v3') || (ufTargetSetupSrv.selectedDevice.subtype==='desktop') ) 
			{
				$window.open(ufTargetSetupSrv.selectedDevice.link, "_blank");
			} else if ( (ufTargetSetupSrv.selectedDevice.subtype==='button') && (ufTargetSetupSrv.selectedDevice.moduleName==='Image Creator') ) {
				ufTargetSetupSrv.started = true;
            	startIC();
			}
			
			return true;
		}
		
		// determine if Image Creator is supported
		function icSupported() {
			let fs = require('fs');
			try {
				return fs.existsSync('../simplelink/imagecreator/');
			}
			catch (e) {
				return false;
			}
		}

		// start the Image Creator process
		function startIC() {
			let exec = require('child_process').execFile;
			let spawn = require('child_process').spawn;
			let StringDecoder = require('string_decoder').StringDecoder;
			let consoleLog;
			
			// get the path to the Image Creator
			let path = require("path");
			let curPath = path.resolve("./")+'/../simplelink/imagecreator/bin/';
			
			// spawn SLImageCreator 
            process = spawn(curPath + 'SLImageCreator', ['misc', '--uniflash'], { cwd: curPath });
            let decoder = new StringDecoder('utf8');
            let port;
            let wsPort;
            // callbacks for the spawned process
            let re = new RegExp("Server Ports: ([0-9]+) ([0-9]+)");
            let matchBuff = ""
            
			// callbacks for the spawned process
            process.stdout.on('data', function (data) {
                let textChunk = decoder.write(data);
                console.log(textChunk);

                if (!(port && wsPort)) {
                    matchBuff += textChunk;
                    let matches = re.exec(matchBuff);
                    if (matches) {
                        port = matches[1];
                        wsPort = matches[2];
                        console.log('Port:' + port);
                        console.log('WS Port:' + wsPort);
                        $window.location.href = 'http://127.0.0.1:' + port + '?x=' + new Date().getTime() + '&r=' + Math.random() + '&p=' + wsPort + '&u=1';
                    }
                }
            });
			
			// stderr callback
			process.stderr.on('data', function (data) {
				console.log('stderr:'+data);
				consoleLog += 'stderr:'+data;
			});

			// close the process
			process.on('close', function (code) {
				console.log('child process exited with code ${code}');
				consoleLog += 'child process exited with code '+code;
				port = "";
			});

		};

		function closeIC() {
			process.stdin.write("\n");
		}
		
		return {
			deviceList: deviceList,
			getDeviceList: getDeviceList,
			getNumFilteredDevices: getNumFilteredDevices,
			selectDevice: selectDevice,
			handleAction: handleAction,
			icSupported: icSupported,
			startIC: startIC
		};
	}

})();
