using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Channels;
using System.Threading.Tasks;

namespace PublishSubscribe
{
    public class ExchangeSender: IDisposable
    {
        private readonly ConnectionFactory _connectionFactory;
        private readonly IConnection _connection;
        private readonly IModel _channel;

        public HashSet<string> Exchanges { get; private set; } = new HashSet<string>();

        public ExchangeSender(string brockerHost, string brockerUsername, string brockerPassword)
        {
            _connectionFactory = new ConnectionFactory() { HostName = brockerHost, UserName = brockerUsername, Password = brockerPassword };
            _connection = _connectionFactory.CreateConnection();
            _channel = _connection.CreateModel();
        }

        public bool AddExcange(string exchange, string exchangeType = ExchangeType.Fanout)
        {
            try
            {
                _channel.ExchangeDeclare(exchange, exchangeType);
                Exchanges.Add(exchange);
                return true;
            }
            catch (Exception ex) 
            {
                Console.WriteLine(ex.Message);
            }
            return false;
        }

        public bool PublishToExchange(string exchange, string message)
        {
            try
            {
                if (!Exchanges.Contains(exchange))
                    return false;

                var messageBody = Encoding.UTF8.GetBytes(message);
                _channel.BasicPublish(exchange: exchange,
                                     routingKey: string.Empty,
                                     basicProperties: null,
                                     body: messageBody);
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            return false;
        }

        ~ExchangeSender() => Dispose();

        public void Dispose()
        {
            _connection.Dispose();
            _channel.Dispose();
        }
    }
}
