using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Aurora.Proto.General;
using Aurora.Proto.Party;

namespace Aurora.Models.Media
{
    public class RemoteAudio : BaseMedia
    {
        private RemotePartyService.RemotePartyServiceClient _remotePartyService;
        private CancellationTokenSource _cancellationTokenSource;

        #region Constructor
        public RemoteAudio(string id,
            bool fromHost,
            AudioMetadata metadata,
            RemotePartyService.RemotePartyServiceClient partyClient)
        {
            this.Id = id;
            this._remotePartyService = partyClient;
            this.Metadata = metadata;
            this.FromHost = fromHost;

            _cancellationTokenSource = new CancellationTokenSource();
        }

        #endregion Constructor

        #region Properties

        public override BaseMetadata Metadata { get; protected set; }

        public override MediaTypeEnum MediaType
        {
            get { return MediaTypeEnum.Audio; }
        }

        public RemotePartyService.RemotePartyServiceClient RemotePartyServiceClient
        {
            get
            {
                return _remotePartyService;
            }
        }

        public bool FromHost { get; private set; }
        #endregion Properties

        /// <summary>
        /// Override load method.
        /// </summary>
        public override async Task Load()
        {
            this.DataStream = new MemoryStream();
            using (var call = _remotePartyService.StreamMedia(new StreamMediaRequest { Name = this.Id }))
            {
                try
                {
                    while (await call.ResponseStream.MoveNext(_cancellationTokenSource.Token))
                    {
                        Chunk chunk = call.ResponseStream.Current;
                        byte[] buffer = chunk.Content.ToByteArray();

                        await this.DataStream.WriteAsync(buffer, 0, buffer.Length);
                    }
                    Console.WriteLine("Done receiving stream");
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception caught while loading remote audio:" + ex.Message);
                }
            }
            await base.Load();
        }

        /// <summary>
        /// Override unload method
        /// </summary>
        public override void Unload()
        {
            // if (!_cancellationTokenSource.IsCancellationRequested)
            // {
            //     _cancellationTokenSource.Cancel();

            //     //Wait for cancellation
            //     WaitHandle.WaitAny(new[] { _cancellationTokenSource.Token.WaitHandle });
            // }
            base.Unload();
        }
    }
}