﻿/*
 * 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 DotPulsar.Abstractions;
using DotPulsar.Internal.Abstractions;
using Extensions;
using PulsarApi;
using System.Buffers;
using System.Collections;
using System.Collections.Generic;

public sealed class BatchHandler<TMessage>
{
    private readonly object _lock;
    private readonly bool _trackBatches;
    private readonly IMessageFactory<TMessage> _messageFactory;
    private readonly Queue<IMessage<TMessage>> _messages;
    private readonly LinkedList<Batch> _batches;

    public BatchHandler(bool trackBatches, IMessageFactory<TMessage> messageFactory)
    {
        _lock = new object();
        _trackBatches = trackBatches;
        _messageFactory = messageFactory;
        _messages = new Queue<IMessage<TMessage>>();
        _batches = new LinkedList<Batch>();
    }

    public IMessage<TMessage> Add(MessageIdData messageId, uint redeliveryCount, MessageMetadata metadata, ReadOnlySequence<byte> data)
    {
        var messages = new List<IMessage<TMessage>>(metadata.NumMessagesInBatch);

        long index = 0;

        for (var i = 0; i < metadata.NumMessagesInBatch; ++i)
        {
            var singleMetadataSize = data.ReadUInt32(index, true);
            index += 4;
            var singleMetadata = Serializer.Deserialize<SingleMessageMetadata>(data.Slice(index, singleMetadataSize));
            index += singleMetadataSize;
            var singleMessageId = new MessageId(messageId.LedgerId, messageId.EntryId, messageId.Partition, i);
            var message = _messageFactory.Create(singleMessageId, redeliveryCount, data.Slice(index, singleMetadata.PayloadSize), metadata, singleMetadata);
            messages.Add(message);
            index += (uint) singleMetadata.PayloadSize;
        }

        lock (_lock)
        {
            if (_trackBatches)
                _batches.AddLast(new Batch(messageId, metadata.NumMessagesInBatch));

            foreach (var message in messages)
            {
                _messages.Enqueue(message);
            }

            return _messages.Dequeue();
        }
    }

    public IMessage<TMessage>? GetNext()
    {
        lock (_lock)
            return _messages.Count == 0 ? null : _messages.Dequeue();
    }

    public void Clear()
    {
        lock (_lock)
        {
            _messages.Clear();
            _batches.Clear();
        }
    }

    public MessageIdData? Acknowledge(MessageIdData messageId)
    {
        lock (_lock)
        {
            foreach (var batch in _batches)
            {
                if (messageId.LedgerId != batch.MessageId.LedgerId ||
                    messageId.EntryId != batch.MessageId.EntryId ||
                    messageId.Partition != batch.MessageId.Partition)
                    continue;

                batch.Acknowledge(messageId.BatchIndex);

                if (batch.IsAcknowledged())
                {
                    _batches.Remove(batch);
                    return batch.MessageId;
                }

                break;
            }

            return null;
        }
    }

    private sealed class Batch
    {
        private readonly BitArray _acknowledgementIndex;

        public Batch(MessageIdData messageId, int numberOfMessages)
        {
            MessageId = messageId;
            _acknowledgementIndex = new BitArray(numberOfMessages, false);
        }

        public MessageIdData MessageId { get; }

        public void Acknowledge(int batchIndex)
            => _acknowledgementIndex.Set(batchIndex, true);

        public bool IsAcknowledged()
        {
            for (var i = 0; i < _acknowledgementIndex.Length; i++)
            {
                if (!_acknowledgementIndex[i])
                    return false;
            }

            return true;
        }
    }
}
