using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using BO.AppServer.Metadata.Dto;
using BO.AppServer.Metadata.Enums;
using BO.Connector;
using Quadarax.Foundation.Core.Data.Interface.Entity.Dto;
using Quadarax.Foundation.Core.Logging;

namespace Connector.PS
{
    public class Connection : AbstractConnection
    {
        #region *** Private fields ***
        protected override string ApiName => "PS";
        private string _psIdentifier;
        #endregion


        #region *** Constructor ***
        public Connection(Uri uriApiBase, TimeSpan timeout,string psIdentifier, ILogHandler log = null, bool isDumpContentEnabled = false) : base(uriApiBase, timeout, log, isDumpContentEnabled)
        {
            if (string.IsNullOrEmpty(psIdentifier))
                throw new ArgumentNullException(nameof(psIdentifier));
            _psIdentifier = psIdentifier;
        }
        #endregion

        #region *** Public operations ***

        public async Task<IEnumerable<DocumentRDto>> GetDocumentsAsync(DocumentsScopeEnums scope)
        {
            if (!(scope == DocumentsScopeEnums.Pending || scope == DocumentsScopeEnums.Working))
                throw new ArgumentOutOfRangeException(
                    $"Document list scope value must be '{DocumentsScopeEnums.Working}' or '{DocumentsScopeEnums.Pending}' int this context.");
            var result = await CallRequestAsync<ResultsValueDto<DocumentRDto>>($"{Ticket}/{_psIdentifier}/documents/{scope}", RestCallTypeEnum.Get);
            return result.Values;
        }

        public async Task<DocumentStatusEnum> GetDocumentStateAsync(long documentId)
        {
            var result = await CallRequestAsync<ResultValueDto<PingDto>>($"{Ticket}/{_psIdentifier}/document/{documentId}", RestCallTypeEnum.Get);
            return Enum.Parse<DocumentStatusEnum>(result.Value.Status);

        }

        public async Task<DocumentStatusEnum> SetDocumentStateAsync(long documentId, DocumentStatusEnum status)
        {
            var result = await CallRequestAsync<ResultValueDto<PingDto>>($"{Ticket}/{_psIdentifier}/document/{documentId}", RestCallTypeEnum.Put,new PingDto(){Status = status.ToString()});
            return Enum.Parse<DocumentStatusEnum>(result.Value.Status);

        }

        public async Task<Stream> GetDocumentContentAsync(long artifactId)
        {
            var result = await CallGetStreamAsync($"{Ticket}/{_psIdentifier}/artifact/{artifactId}");
            return result;
        }
        #endregion


        #region *** Private operations and overrides ***
        protected override void OnOpening()
        {
            base.OnOpening();
            var result = Task.Run(() =>  CallRequestAsync<ResultPlain>($"{Ticket}/register", RestCallTypeEnum.Post, new PingDto(){Status = _psIdentifier}));
            if (!result.Result.IsSuccess)
                throw result.Result.ToAggregateException();
            Log(LogSeverityEnum.Info,$"Process server '{_psIdentifier}' is registered.");
        }
        #endregion
    }
}
