(function () {
    /*global saveAs, TICloudAgent*/
    'use strict';
    angular.module('uniflash').directive('ufDownloadPackage', downloadPackage);
    function downloadPackage() {
        var directive = {
            restrict: 'E',
            controller: StandaloneDownload,
            controllerAs: 'vm',
            templateUrl: 'standalone_dl/download_package.template.html',
            scope: {}
        };
        return directive;
    }
    StandaloneDownload.$inject = ['$q', '$scope', '$state', '$log',
        'ufFilePackageCreator', 'ufPropertiesValue', 'ufTargetConfig', 'ufPrograms', 'ufMainView', 'ticAlerts', 'ufSession', 'ufProgess', 'ticExecutionPlatform', 'ticAnalyticsSrv'];
    function StandaloneDownload($q, $scope, $state, $log, ufFilePackageCreator, ufPropertiesValue, ufTargetConfig, ufPrograms, ufMainView, ticAlerts, ufSession, ufProgess, ticExecutionPlatform, ticAnalyticsSrv) {
        var vm = this;
        vm.isRunningCloud = ticExecutionPlatform.getPlatform() === ti_common.PlatformType.CLOUD;
        vm.ufProgramList = ufPrograms.getPrograms();
        vm.selectedPrograms = 0;
        vm.cliScriptName = [];
        vm.cliScriptName['Windows'] = 'dslite.bat';
        vm.cliScriptName['Linux'] = 'dslite.sh';
        vm.cliScriptName['OSX'] = 'dslite.sh';
        if (!vm.ufProgramList) {
            vm.ufProgramList = [];
        }
        _.each(vm.ufProgramList, function (image) {
            if (image.isSelected) {
                vm.selectedPrograms++;
            }
        });
        vm.includeSettings = true;
        vm.includeImages = (vm.selectedPrograms > 0);
        vm.includeDrivers = false;
        vm.includeSessions = false;
        ufTargetConfig.getDevice($state.params.deviceXMLFile)
            .then(function (device) {
            vm.deviceName = device.id;
            return ufTargetConfig.getConnection(device.connectionIndices, $state.params.connectionXMLFile);
        })
            .then(function (connection) {
            vm.connectionName = connection.id;
        });
        var osDesc = {
            'Windows': 'win',
            'OSX': 'osx',
            'Linux': 'linux'
        };
        vm.osTypes = ['Windows', 'OSX', 'Linux'];
        switch (ufFilePackageCreator.getOSType()) {
            case 'win':
                vm.choosenOsType = vm.osTypes[0];
                break;
            case 'osx':
                vm.choosenOsType = vm.osTypes[1];
                break;
            case 'linux':
                vm.choosenOsType = vm.osTypes[2];
                break;
        }
        vm.packageName = 'uniflash_' + vm.choosenOsType.toLowerCase();
        vm.updatePackageName = function () {
            if (vm.packageName.substring(0, 9) === 'uniflash_') {
                vm.packageName = 'uniflash_' + vm.choosenOsType.toLowerCase();
            }
        };
        function isSafari() {
            return 'safari' === TICloudAgent.getBrowser();
        }
        function b64toBlob(b64Data, contentType, sliceSize) {
            contentType = contentType || '';
            sliceSize = sliceSize || 512;
            var byteCharacters = atob(b64Data);
            var byteArrays = [];
            for (var offset = 0; offset < byteCharacters.length; offset += sliceSize) {
                var slice = byteCharacters.slice(offset, offset + sliceSize);
                var byteNumbers = new Array(slice.length);
                for (var i = 0; i < slice.length; i++) {
                    byteNumbers[i] = slice.charCodeAt(i);
                }
                var byteArray = new Uint8Array(byteNumbers);
                byteArrays.push(byteArray);
            }
            var blob = new Blob(byteArrays, { type: contentType });
            return blob;
        }
        function generateDownloadLink(name, abContent) {
            if (isSafari()) {
                var base64data = arrayBufferToBase64(abContent);
                window.location.href = 'data:application/zip;base64,' + base64data;
            }
            else {
                var byteArray = new Uint8Array(abContent);
                var textFileAsBlob = new Blob([byteArray], { type: 'application/zip' });
                saveAs(textFileAsBlob, name);
            }
        }
        function arrayBufferToBase64(buffer) {
            var binary = '';
            var bytes = new Uint8Array(buffer);
            var len = bytes.byteLength;
            for (var i = 0; i < len; i++) {
                binary += String.fromCharCode(bytes[i]);
            }
            return window.btoa(binary);
        }
        vm.download = function () {
            var choosenOptions = {
                'includeImages': vm.includeImages,
                'includeSettings': vm.includeSettings,
                'os': vm.choosenOsType
            };
            ticAnalyticsSrv.record('DownloadPackage', choosenOptions);
            $log.debug('DownloadPackage: ' + JSON.stringify(choosenOptions));
            var progressDialog, zipFileContents;
            ufFilePackageCreator.setOSType(osDesc[vm.choosenOsType]);
            ufFilePackageCreator.setPackageOptions(vm.includeImages, vm.includeSettings, vm.includeDrivers, vm.includeSessions);
            ufFilePackageCreator.setDevice(vm.deviceName);
            ufFilePackageCreator.getFilePackage()
                .then(function (contents) {
                zipFileContents = contents;
                $log.debug('Fetching package files successful.');
                return ufFilePackageCreator.getProgess();
            })
                .then(function (newProgressDialog) {
                progressDialog = newProgressDialog;
                var platform = (vm.choosenOsType === 'Windows') ? 'DOS' : 'UNIX';
                var type = 'arraybuffer';
                var deferred = $q.defer();
                var totalFiles = zipFileContents.length;
                var myWorker = new Worker('standalone_dl/jszip.worker.js');
                myWorker.addEventListener('message', function (msg) {
                    if (msg.data.isDone) {
                        progressDialog.handleEvent({
                            name: 'Zip Package created.',
                            subActivity: 'You may need to check for a file dialog if to save the zip file.',
                            isCancellable: false,
                        }, null);
                        deferred.resolve(msg.data.output);
                    }
                    else {
                        var p = msg.data.percent / 2 + 50;
                        var progressMsg = 'Creating Zip Package: ' + msg.data.currentFile;
                        if (p === 100 && msg.data.currentFile === null) {
                            progressMsg = 'Done';
                        }
                        progressDialog.handleEvent({
                            name: 'Creating Zip Package...',
                            percent: p,
                            subActivity: progressMsg,
                            isCancellable: false,
                        }, null);
                    }
                });
                myWorker.postMessage({
                    action: 'start'
                });
                angular.forEach(zipFileContents, function (file) {
                    if (typeof file.contents === 'string') {
                        myWorker.postMessage({
                            action: 'addFile',
                            filename: file.fileName,
                            contents: file.contents,
                            options: JSON.stringify(file.options)
                        });
                    }
                    else {
                        myWorker.postMessage({
                            action: 'addFile',
                            filename: file.fileName,
                            contents: file.contents,
                            options: JSON.stringify(file.options)
                        }, [
                            file.contents
                        ]);
                    }
                });
                //  console.log('generate zip...');
                myWorker.postMessage({
                    action: 'generate',
                    type: type,
                    platform: platform
                });
                return deferred.promise;
            })
                .then(function (content) {
                if (!vm.packageName) {
                    vm.packageName = 'uniflash-' + vm.choosenOsType;
                }
                generateDownloadLink(vm.packageName + '.zip', content);
            })
                .catch(function (error) {
                return displayError(error);
            })
                .finally(function () {
                progressDialog.close();
            });
        };
        function displayError(e) {
            if (typeof e === 'string') {
                return ticAlerts.showError(e);
            }
            else if (e && e.message && typeof e.message === 'string') {
                return ticAlerts.showError(e.message);
            }
            else {
                $log.error(JSON.stringify(e));
            }
        }
        //download value-xml string for the current core as a file
        vm.dlCurrentSettings = function () {
            var filename = 'settings.ufsettings';
            var blob = new Blob([ufPropertiesValue.saveValuesAsJson(true)], {
                type: 'application/json;charset=utf-8'
            });
            saveAs(blob, filename);
            $log.info('Fetching settings for ' + filename);
        };
        vm.goToUtilitiesAndSettings = function () {
            ufMainView.go(uniflash.RegisteredViews.UtilitiesAndSettings, $state.params.coreName);
        };
        vm.goToPrograms = function () {
            ufMainView.go(uniflash.RegisteredViews.Program, $state.params.coreName);
        };
    }
}());
