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

public sealed class ConsumerBuilder<TMessage> : IConsumerBuilder<TMessage>
{
    private readonly IPulsarClient _pulsarClient;
    private readonly ISchema<TMessage> _schema;
    private string? _consumerName;
    private SubscriptionInitialPosition _initialPosition;
    private int _priorityLevel;
    private uint _messagePrefetchCount;
    private bool _readCompacted;
    private string? _subscriptionName;
    private SubscriptionType _subscriptionType;
    private string? _topic;
    private IHandleStateChanged<ConsumerStateChanged>? _stateChangedHandler;

    public ConsumerBuilder(IPulsarClient pulsarClient, ISchema<TMessage> schema)
    {
        _schema = schema;
        _pulsarClient = pulsarClient;
        _initialPosition = ConsumerOptions<TMessage>.DefaultInitialPosition;
        _priorityLevel = ConsumerOptions<TMessage>.DefaultPriorityLevel;
        _messagePrefetchCount = ConsumerOptions<TMessage>.DefaultMessagePrefetchCount;
        _readCompacted = ConsumerOptions<TMessage>.DefaultReadCompacted;
        _subscriptionType = ConsumerOptions<TMessage>.DefaultSubscriptionType;
    }

    public IConsumerBuilder<TMessage> ConsumerName(string name)
    {
        _consumerName = name;
        return this;
    }

    public IConsumerBuilder<TMessage> InitialPosition(SubscriptionInitialPosition initialPosition)
    {
        _initialPosition = initialPosition;
        return this;
    }

    public IConsumerBuilder<TMessage> MessagePrefetchCount(uint count)
    {
        _messagePrefetchCount = count;
        return this;
    }

    public IConsumerBuilder<TMessage> PriorityLevel(int priorityLevel)
    {
        _priorityLevel = priorityLevel;
        return this;
    }

    public IConsumerBuilder<TMessage> ReadCompacted(bool readCompacted)
    {
        _readCompacted = readCompacted;
        return this;
    }

    public IConsumerBuilder<TMessage> StateChangedHandler(IHandleStateChanged<ConsumerStateChanged> handler)
    {
        _stateChangedHandler = handler;
        return this;
    }

    public IConsumerBuilder<TMessage> SubscriptionName(string name)
    {
        _subscriptionName = name;
        return this;
    }

    public IConsumerBuilder<TMessage> SubscriptionType(SubscriptionType type)
    {
        _subscriptionType = type;
        return this;
    }

    public IConsumerBuilder<TMessage> Topic(string topic)
    {
        _topic = topic;
        return this;
    }

    public IConsumer<TMessage> Create()
    {
        if (string.IsNullOrEmpty(_subscriptionName))
            throw new ConfigurationException("SubscriptionName may not be null or empty");

        if (string.IsNullOrEmpty(_topic))
            throw new ConfigurationException("Topic may not be null or empty");

        var options = new ConsumerOptions<TMessage>(_subscriptionName!, _topic!, _schema)
        {
            ConsumerName = _consumerName,
            InitialPosition = _initialPosition,
            MessagePrefetchCount = _messagePrefetchCount,
            PriorityLevel = _priorityLevel,
            ReadCompacted = _readCompacted,
            StateChangedHandler = _stateChangedHandler,
            SubscriptionType = _subscriptionType
        };

        return _pulsarClient.CreateConsumer(options);
    }
}
