using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

using RabbitMQ;
using RabbitMQ.Client;

// Need to install RabbitMQ Server
// http://www.rabbitmq.com/

namespace RabbitClientCS
{
    class Program
    {
        static void Send()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

                string message = "Hello World from TIM!";
                var body = Encoding.UTF8.GetBytes(message);

                channel.BasicPublish(exchange: "", routingKey: "hello", basicProperties: null, body: body);
                Console.WriteLine(" [x] Sent {0}", message);
            }
        }

        static void Receive()
        {
            var factory = new ConnectionFactory() { HostName = "localhost" };
            using (var connection = factory.CreateConnection())
            using (var channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue: "hello", durable: false, exclusive: false, autoDelete: false, arguments: null);

                var consumer = new RabbitMQ.Client.Events.EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);
                };
                channel.BasicConsume(queue: "hello", autoAck: true, consumer: consumer);
            }
            Thread.Sleep(1000);            
        }

        static void Main(string[] args)
        {
            CRabbitMQ rmq = new CRabbitMQ();
            rmq.Connect("localhost");

            if (args[0] == "-s")
            {
                rmq.Send(args[1]);
            }
            else
            {
                string reply = string.Empty;
                rmq.Recv(ref reply);
                Console.WriteLine(reply);
            }
            return;
        }
    }

    class CRabbitMQ
    {
        private string queue = "TESTQ";
        private ConnectionFactory connectionFactory = null;
        private IConnection connection = null;

        ~CRabbitMQ()
        {
            Disconnect();
        }

        public IConnection Connect(string host)
        {
            connectionFactory = new ConnectionFactory();
            connectionFactory.HostName = host;
            //connectionFactory.Port = 5555;
            //connectionFactory.UserName = userName;
            //connectionFactory.Password = password;
            connection = connectionFactory.CreateConnection();
            return connection;
        }

        public void Disconnect()
        {
            if (connection.IsOpen)
            {
                connection.Close();
                connection = null;
            }
        }

        public int Send(string str)
        {
            using (IModel channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue, false, false, false, null);
                channel.BasicPublish(string.Empty, queue, null, Encoding.UTF8.GetBytes(str));
            }
            return str.Length;
        }

        public int Recv(ref string str)
        {
            using (IModel channel = connection.CreateModel())
            {
                channel.QueueDeclare(queue, false, false, false, null);
                var consumer = new RabbitMQ.Client.Events.EventingBasicConsumer(channel);
                BasicGetResult result = channel.BasicGet(queue, true);
                if (result != null)
                {
                    str = Encoding.UTF8.GetString(result.Body);
                }
            }
            return str.Length;
        }
    }
}