(function () {

    'use strict';

    angular.module('uniflash').directive('ufConnectionState', connectionState);

    function connectionState() {

        var directive = {
            restrict: 'E',
            controller: ConnectionState,
            controllerAs: 'vm',
            templateUrl: 'ds/connection_state.template.html',
            scope: {},
        };
        return directive;
    }


    class ConnectionState {
        static $inject = ['$scope', '$rootScope', '$log', 'ufPreferencesSrv', 'ufSession', 'ufDS', 'ufDsProgressDialog'];
        public remainConnected;
        public connectionStatus = {};
        public cores = this.ufSession.queryConfig().cores;
        private dsOpInProgress;

        constructor(private $scope, private $rootScope, private $log, private ufPreferencesSrv, private ufSession: uniflash.session.SessionService, private ufDS, private ufDsProgressDialog) {
            //init value
            this.remainConnected = !ufPreferencesSrv.get('Auto Disconnect');
            //update gui value back to service
            $scope.$watch('vm.remainConnected', (newVal, oldVal) => {
                if (newVal !== oldVal) {
                    ufPreferencesSrv.set('Auto Disconnect', !newVal);
                }
            });

            let listeners = {};
            angular.forEach(this.cores, (core) => {
                let coreName = core.name;
                let listener = this.getTargetStateListener(coreName);
                this.ufDS.addTargetStateListener((coreName), listener);
                listeners[coreName] = listener;
            });

            $scope.$on('$destroy', () => {
                angular.forEach(listeners, (listener, coreName) => {
                    this.ufDS.removeTargetStateListener((coreName), listener);
                });
            });

            $scope.$on('$destroy', $rootScope.$on('ds.opStarted', () => {
                this.dsOpInProgress = true;
            }));

            $scope.$on('$destroy', $rootScope.$on('ds.opFinished', () => {
                this.dsOpInProgress = false;
            }));
        }

        isConfigured() {
            return this.ufDS.isConfigured();
        }

        isConnected(coreName: string) {
            return (this.ufDS.getCachedConnectedCores()[coreName]) ? true : false;
        }

        isAnyCoreConnected() {
            return (Object.keys(this.ufDS.getCachedConnectedCores()).length > 0);
        }

        getTargetStateListener(coreName: string) {
            return (status) => {
                if (this.isConnected(coreName)) {
                    this.connectionStatus[coreName] = status.description;
                } else {
                    this.connectionStatus[coreName] = status.description ? status.description : 'Disconnected';
                }
            };
        }

        disconnectAllCores() {
            this.$log.debug('ConnectionState: disconnectAllCores()');
            this.ufDsProgressDialog.disconnectAllCores();
        }

        configure() {
            this.ufDsProgressDialog.configureDS();
        }

        deconfigure() {
            this.ufDsProgressDialog.deconfigureDS();
        }
    }
})();