﻿/*
 * 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.
 */

namespace DotPulsar.Internal
{
    using Abstractions;
    using Extensions;
    using Microsoft.Extensions.ObjectPool;
    using PulsarApi;
    using System;
    using System.Buffers;
    using System.Threading;
    using System.Threading.Tasks;

    public sealed class ProducerChannel : IProducerChannel
    {
        private readonly ObjectPool<SendPackage> _sendPackagePool;
        private readonly ulong _id;
        private readonly string _name;
        private readonly IConnection _connection;
        private readonly ICompressorFactory? _compressorFactory;
        private readonly byte[]? _schemaVersion;

        public ProducerChannel(
            ulong id,
            string name,
            IConnection connection,
            ICompressorFactory? compressorFactory,
            byte[]? schemaVersion)
        {
            var sendPackagePolicy = new DefaultPooledObjectPolicy<SendPackage>();
            _sendPackagePool = new DefaultObjectPool<SendPackage>(sendPackagePolicy);
            _id = id;
            _name = name;
            _connection = connection;
            _compressorFactory = compressorFactory;
            _schemaVersion = schemaVersion;
        }

        public async ValueTask ClosedByClient(CancellationToken cancellationToken)
        {
            try
            {
                var closeProducer = new CommandCloseProducer { ProducerId = _id };
                await _connection.Send(closeProducer, cancellationToken).ConfigureAwait(false);
            }
            catch
            {
                // Ignore
            }
        }

        public ValueTask DisposeAsync() => new ValueTask();

        public async Task<CommandSendReceipt> Send(MessageMetadata metadata, ReadOnlySequence<byte> payload, CancellationToken cancellationToken)
        {
            var sendPackage = _sendPackagePool.Get();

            try
            {
                metadata.PublishTime = (ulong) DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
                metadata.ProducerName = _name;

                if (metadata.SchemaVersion is null && _schemaVersion is not null)
                    metadata.SchemaVersion = _schemaVersion;

                if (sendPackage.Command is null)
                {
                    sendPackage.Command = new CommandSend
                    {
                        ProducerId = _id,
                        NumMessages = 1
                    };
                }

                sendPackage.Command.SequenceId = metadata.SequenceId;
                sendPackage.Metadata = metadata;

                if (_compressorFactory is null)
                    sendPackage.Payload = payload;
                else
                {
                    sendPackage.Metadata.Compression = _compressorFactory.CompressionType;
                    sendPackage.Metadata.UncompressedSize = (uint) payload.Length;
                    using var compressor = _compressorFactory.Create();
                    sendPackage.Payload = compressor.Compress(payload);
                }

                var response = await _connection.Send(sendPackage, cancellationToken).ConfigureAwait(false);
                response.Expect(BaseCommand.Type.SendReceipt);
                return response.SendReceipt;
            }
            finally
            {
                _sendPackagePool.Return(sendPackage);
            }
        }
    }
}
