text: angular.module('portainer.services')
  .factory('StateManager', ['$q', 'SystemService', 'InfoHelper', 'LocalStorage', 'SettingsService', 'StatusService', function StateManagerFactory($q, SystemService, InfoHelper, LocalStorage, SettingsService, StatusService) {
    'use strict';
  
    var manager = {};
  
    var state = {
      loading: true,
      application: {},
      endpoint: {},
      UI: {}
    };
  
    manager.getState = function() {
      return state;
    };
  
    manager.clean = function () {
      state.endpoint = {};
    };
  
    manager.updateLogo = function(logoURL) {
      state.application.logo = logoURL;
      LocalStorage.storeApplicationState(state.application);
    };
  
    manager.updateExternalContributions = function(displayExternalContributors) {
      state.application.displayExternalContributors = displayExternalContributors;
      LocalStorage.storeApplicationState(state.application);
    };
  
    manager.initialize = function () {
      var deferred = $q.defer();
  
      var endpointState = LocalStorage.getEndpointState();
      if (endpointState) {
        state.endpoint = endpointState;
      }
  
      var applicationState = LocalStorage.getApplicationState();
      if (applicationState) {
        state.application = applicationState;
        state.loading = false;
        deferred.resolve(state);
      } else {
        $q.all({
          settings: SettingsService.publicSettings(),
          status: StatusService.status()
        })
        .then(function success(data) {
          var status = data.status;
          var settings = data.settings;
          state.application.authentication = status.Authentication;
          state.application.analytics = status.Analytics;
          state.application.endpointManagement = status.EndpointManagement;
          state.application.version = status.Version;
          state.application.logo = settings.LogoURL;
          state.application.displayExternalContributors = settings.DisplayExternalContributors;
          LocalStorage.storeApplicationState(state.application);
          deferred.resolve(state);
        })
        .catch(function error(err) {
          deferred.reject({msg: 'Unable to retrieve server settings and status', err: err});
        })
        .finally(function final() {
          state.loading = false;
        });
      }
  
      return deferred.promise;
    };
  
    manager.updateEndpointState = function(loading) {
      var deferred = $q.defer();
      if (loading) {
        state.loading = true;
      }
      $q.all({
        info: SystemService.info(),
        version: SystemService.version()
      })
      .then(function success(data) {
        var endpointMode = InfoHelper.determineEndpointMode(data.info);
        var endpointAPIVersion = parseFloat(data.version.ApiVersion);
        state.endpoint.mode = endpointMode;
        state.endpoint.apiVersion = endpointAPIVersion;
        LocalStorage.storeEndpointState(state.endpoint);
        deferred.resolve();
      })
      .catch(function error(err) {
        deferred.reject({msg: 'Unable to connect to the Docker endpoint', err: err});
      })
      .finally(function final() {
        state.loading = false;
      });
  
      return deferred.promise;
    };
  
    return manager;
  }]);
  