namespace ByteBard.AsyncAPI.Bindings
{
    using System;
    using System.Collections.Generic;
    using ByteBard.AsyncAPI.Bindings.AMQP;
    using ByteBard.AsyncAPI.Bindings.Http;
    using ByteBard.AsyncAPI.Bindings.Kafka;
    using ByteBard.AsyncAPI.Bindings.MQTT;
    using ByteBard.AsyncAPI.Bindings.Pulsar;
    using ByteBard.AsyncAPI.Bindings.Sns;
    using ByteBard.AsyncAPI.Bindings.Sqs;
    using ByteBard.AsyncAPI.Bindings.WebSockets;
    using ByteBard.AsyncAPI.Models.Interfaces;
    using ByteBard.AsyncAPI.Readers.Interface;

    public static class BindingsCollection
    {
        public static TCollection Add<TCollection, TItem>(
    this TCollection destination,
    IEnumerable<TItem> source)
    where TCollection : ICollection<TItem>
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            if (destination is List<TItem> list)
            {
                list.AddRange(source);
                return destination;
            }

            foreach (var item in source)
            {
                destination.Add(item);
            }

            return destination;
        }

        public static ICollection<IBindingParser<IBinding>> All => new List<IBindingParser<IBinding>>
        {
            Pulsar,
            Kafka,
            Http,
            Websockets,
            Sqs,
            Sns,
            AMQP,
            MQTT,
        };

        public static ICollection<IBindingParser<IBinding>> Http => new List<IBindingParser<IBinding>>
        {
            new HttpOperationBinding(),
            new HttpMessageBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> Websockets => new List<IBindingParser<IBinding>>
        {
            new WebSocketsChannelBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> Kafka => new List<IBindingParser<IBinding>>
        {
            new KafkaServerBinding(),
            new KafkaChannelBinding(),
            new KafkaOperationBinding(),
            new KafkaMessageBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> Pulsar => new List<IBindingParser<IBinding>>
        {
            new PulsarServerBinding(),
            new PulsarChannelBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> Sqs => new List<IBindingParser<IBinding>>
        {
            new SqsChannelBinding(),
            new SqsOperationBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> Sns => new List<IBindingParser<IBinding>>
        {
            new SnsChannelBinding(),
            new SnsOperationBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> AMQP => new List<IBindingParser<IBinding>>
        {
            new AMQPChannelBinding(),
            new AMQPOperationBinding(),
            new AMQPMessageBinding(),
        };

        public static ICollection<IBindingParser<IBinding>> MQTT => new List<IBindingParser<IBinding>>
        {
            new MQTTServerBinding(),
            new MQTTOperationBinding(),
            new MQTTMessageBinding(),
        };
    }
}
