using Alchemy.Classes;
using MediaBrowser.Common.Net;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Net;
using System;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.WebSocket
{
    /// 
    /// Class AlchemyWebSocket
    /// 
    public class AlchemyWebSocket : IWebSocket
    {
        /// 
        /// The logger
        /// 
        private readonly ILogger _logger;
        /// 
        /// Gets or sets the web socket.
        /// 
        /// The web socket.
        private UserContext UserContext { get; set; }
        /// 
        /// Initializes a new instance of the  class.
        /// 
        /// The context.
        /// The logger.
        /// context
        public AlchemyWebSocket(UserContext context, ILogger logger)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            _logger = logger;
            UserContext = context;
            context.SetOnDisconnect(OnDisconnected);
            context.SetOnReceive(OnReceiveContext);
            _logger.Info("Client connected from {0}", context.ClientAddress);
        }
        /// 
        /// The _disconnected
        /// 
        private bool _disconnected;
        /// 
        /// Gets or sets the state.
        /// 
        /// The state.
        public WebSocketState State
        {
            get { return _disconnected ? WebSocketState.Closed : WebSocketState.Open; }
        }
        /// 
        /// Called when [disconnected].
        /// 
        /// The context.
        private void OnDisconnected(UserContext context)
        {
            _disconnected = true;
        }
        /// 
        /// Called when [receive].
        /// 
        /// The context.
        private void OnReceiveContext(UserContext context)
        {
            if (OnReceive != null)
            {
                var json = context.DataFrame.ToString();
                OnReceive(json);
            }
        }
        
        /// 
        /// Sends the async.
        /// 
        /// The bytes.
        /// The type.
        /// if set to true [end of message].
        /// The cancellation token.
        /// Task.
        public Task SendAsync(byte[] bytes, WebSocketMessageType type, bool endOfMessage, CancellationToken cancellationToken)
        {
            UserContext.Send(bytes);
            return Task.FromResult(true);
        }
        /// 
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// 
        public void Dispose()
        {
            Dispose(true);
        }
        /// 
        /// Releases unmanaged and - optionally - managed resources.
        /// 
        /// true to release both managed and unmanaged resources; false to release only unmanaged resources.
        protected virtual void Dispose(bool dispose)
        {
        }
        /// 
        /// Gets or sets the receive action.
        /// 
        /// The receive action.
        public Action OnReceiveBytes { get; set; }
        /// 
        /// Gets or sets the on receive.
        /// 
        /// The on receive.
        public Action OnReceive { get; set; }
    }
}