using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
using System.Collections.Concurrent;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Library
{
    /// 
    /// Class DisplayPreferencesManager
    /// 
    public class DisplayPreferencesManager : IDisplayPreferencesManager
    {
        /// 
        /// The _logger
        /// 
        private readonly ILogger _logger;
        /// 
        /// The _display preferences
        /// 
        private readonly ConcurrentDictionary> _displayPreferences = new ConcurrentDictionary>();
        /// 
        /// Gets the active user repository
        /// 
        /// The display preferences repository.
        public IDisplayPreferencesRepository Repository { get; set; }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The logger.
        public DisplayPreferencesManager(ILogger logger)
        {
            _logger = logger;
        }
        /// 
        /// Gets the display preferences.
        /// 
        /// The display preferences id.
        /// DisplayPreferences.
        public Task GetDisplayPreferences(Guid displayPreferencesId)
        {
            return _displayPreferences.GetOrAdd(displayPreferencesId, keyName => RetrieveDisplayPreferences(displayPreferencesId));
        }
        /// 
        /// Retrieves the display preferences.
        /// 
        /// The display preferences id.
        /// DisplayPreferences.
        private async Task RetrieveDisplayPreferences(Guid displayPreferencesId)
        {
            var displayPreferences = await Repository.GetDisplayPreferences(displayPreferencesId).ConfigureAwait(false);
            return displayPreferences ?? new DisplayPreferences { Id = displayPreferencesId };
        }
        /// 
        /// Saves display preferences for an item
        /// 
        /// The display preferences.
        /// The cancellation token.
        /// Task.
        public async Task SaveDisplayPreferences(DisplayPreferences displayPreferences, CancellationToken cancellationToken)
        {
            if (displayPreferences == null)
            {
                throw new ArgumentNullException("displayPreferences");
            }
            if (displayPreferences.Id == Guid.Empty)
            {
                throw new ArgumentNullException("displayPreferences.Id");
            }
            try
            {
                await Repository.SaveDisplayPreferences(displayPreferences,
                                                                                        cancellationToken).ConfigureAwait(false);
                var newValue = Task.FromResult(displayPreferences);
                // Once it succeeds, put it into the dictionary to make it available to everyone else
                _displayPreferences.AddOrUpdate(displayPreferences.Id, newValue, delegate { return newValue; });
            }
            catch (Exception ex)
            {
                _logger.ErrorException("Error saving display preferences", ex);
                throw;
            }
        }
    }
}