
/*
 * Copyright 2017-present Open Networking Foundation

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 * http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */


(function () {
  
  angular.module('xos.helpers')

  /**
  * @ngdoc service
  * @name xos.helpers.XosUserPrefs
  * @description
  * This service is used to store the user preferences in cookies, so that they survive to page changes.
  * The structure of the user preference is:
  * ```
  * {
  *   synchronizers: {
  *     notification: {
  *       'volt': boolean,
  *       'openstack': boolean,
  *       ...
  *     }
  *   }
  *   userData: {
  *     current_user_site_id: Number,
  *     current_user_site_user_names: Array[1],
  *     ...
  *     }
  * }
  * ```
  **/

  .service('XosUserPrefs', function($cookies, Me, $q){

    let userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};

    /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#getAll
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Return all the user preferences stored in cookies
    * @returns {object} The user preferences
    **/
    this.getAll = () => {
      userPrefs = $cookies.get('xosUserPrefs') ? angular.fromJson($cookies.get('xosUserPrefs')) : {};
      return userPrefs;
    };

    /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#setAll
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Override all user preferences
    * @param {object} prefs The user preferences
    **/
    this.setAll = (prefs) => {
      $cookies.put('xosUserPrefs', angular.toJson(prefs));
    };

    /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#getSynchronizerNotificationStatus
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Return the synchronizer notification status, if name is not provided return the status for all synchronizers
    * @param {string=} prefs The synchronizer name
    * @returns {object | string} The synchronizer status
    **/
    this.getSynchronizerNotificationStatus = (name = false) => {
      if(name){
        return this.getAll().synchronizers.notification[name];
      }
      return this.getAll().synchronizers.notification;
    };


    /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#getUserDetailsCookie
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Return all the user details stored in cookies or call the service
    * @returns {object} The user details
    **/
    this.getUserDetailsCookie = () => {
      const defer = $q.defer();
      let localPref  = this.getAll();
      if(!localPref.userData){
        this.setUserDetailsCookie().$promise.then((data)=>{
          defer.resolve(data);
        });
      }
      else{
        defer.resolve(localPref.userData);
      }
      return {$promise: defer.promise};
    };

    /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#setUserDetailsCookie
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Save the user details in the cookie
    * @param {object} details stored in cookie
    * @param {objects} returns the user details as a promise
    **/
    this.setUserDetailsCookie = (userData = null)=> {

      const defer = $q.defer();
      let cookies = this.getAll();
      if (!userData){
        Me.get().then((user)=> {
          cookies.userData = user;
          this.setAll(cookies);
          defer.resolve(user);
        })
        .catch ((e) => {
          defer.reject(e);
        });
      }
      else {
        cookies.userData = userData;
        this.setAll(cookies);
        defer.resolve(userData);
      }
      return {$promise: defer.promise};
    }

     /**
    * @ngdoc method
    * @name xos.helpers.XosUserPrefs#setSynchronizerNotificationStatus
    * @methodOf xos.helpers.XosUserPrefs
    * @description
    * Update the notification status for a single synchronizer
    * @param {string} name The synchronizer name
    * @param {boolean} value The notification status (true means that it has been sent)
    **/

    this.setSynchronizerNotificationStatus = (name = false, value) => {
      if(!name){
        throw new Error('[XosUserPrefs] When updating a synchronizer is mandatory to provide a name.')
      }

      let cookies = this.getAll();

      if(!cookies.synchronizers){
        cookies.synchronizers = {
          notification: {}
        }
      }
      cookies.synchronizers.notification[name] = value;
      this.setAll(cookies);
    }
  });
})();