using System;
using System.Collections.Generic;
using System.Text;
using iNTERFACEWARE.IGC;

namespace IGCexample
{
    class IGCexampleMain
    {
        public System.Threading.AutoResetEvent StopEvent;
        public MessageProcessor Processor;

        IGCexampleMain()
        {
            Processor = new MessageProcessor();
            StopEvent = new System.Threading.AutoResetEvent(false);
        }

        // This event is triggered when a message is received.
        public void MessageReceivedHandler(object sender, System.EventArgs e, string Message,
            MessageReceivedResponse MessageResponse)
        {
            // Note that exceptions can never be thrown outside the handler.
            try
            {
                // Message processing goes here. This example just prints the received message as is.
                System.Console.WriteLine("*** Message Received ***");
                System.Console.WriteLine(Message);
                System.Console.WriteLine("");

                // Tell Iguana that the message has been successfully processed.
                MessageResponse.MessageProcessed = true;

                // If the plugin is unable to process the message right away (for example,
                // because the plugin is attempting to communicate with a database that is
                // sometimes unavailable), you can tell Iguana to wait a specified number of
                // milliseconds before resending the message.
                //
                //    MessageResponse.MessageProcessed = false;
                //    MessageResponse.ResendMessage = true;
                //    MessageResponse.ResendMessageDelay = 1000;

                // Or you can tell Iguana to stop the channel and resend the message after the
                // channel is restarted.
                //
                //    MessageResponse.MessageProcessed = false;
                //    MessageResponse.ResendMessage = true;
                //    MessageResponse.StopChannel = true;

                // You can use StopChannel, StopChannelErrorFlag, and StopChannelReason to stop the Iguana 
                // channel with or without an error flag, and provide a reason for the stop request.
                //
                //    MessageResponse.StopChannel = true;
                //    MessageResponse.StopChannelErrorFlag = true;
                //    MessageResponse.StopChannelReason = "An error occurred.";

                // You can send additional error/info/debug log messages to Iguana with addLogMessage().
                //
                //    MessageResponse.addLogMessage( IGClogMessageType.Error, "Error log message" );
                //    MessageResponse.addLogMessage( IGClogMessageType.Info,  "Info log message" );
                //    MessageResponse.addLogMessage( IGClogMessageType.Debug, "Debug log message" );
                //    MessageResponse.addLogMessage( IGClogMessageType.Warning, "Warning log message" );

                // You can use addLogValue() to send additional Key/Value pair logging information to Iguana.
                //
                //    MessageResponse.AddLogValue("MyField", "Message successfully processed.");
            }
            catch (iNTERFACEWARE.IGC.Exception Error)
            {
                System.Console.WriteLine(Error.Description);
            }
            catch (System.Exception Error)
            {
                System.Console.WriteLine(Error.Message);
            }
        }

        // This event is triggered when the connection to Iguana is closed.
        public void DisconnectHandler(object sender, System.EventArgs e,
            MessageProcessor.IGCdisconnectReasonFlags ReasonFlags, string ReasonDescription)
        {
            // Note that exceptions can never be thrown outside the handler.
            try
            {
                // Stop the main thread and exit the program.
                if (MessageProcessor.isDisconnectByError(ReasonFlags))
                {
                    System.Console.WriteLine("Connection closed by error: " + ReasonDescription);
                }
                else if (MessageProcessor.isDisconnectByPlugin(ReasonFlags))
                {
                    System.Console.WriteLine("Plugin closed the connection");
                }
                else if (MessageProcessor.isDisconnectByIguana(ReasonFlags))
                {
                    System.Console.WriteLine("Iguana closed the connection");
                }
                else
                {
                    System.Console.WriteLine("Connection closed: " + ReasonDescription);
                }

                StopEvent.Set();
            }
            catch (iNTERFACEWARE.IGC.Exception Error)
            {
                System.Console.WriteLine(Error.Description);
            }
            catch (System.Exception Error)
            {
                System.Console.WriteLine(Error.Message);
            }
        }

        static void Main(string[] args)
        {
            // Usage matches default executable parameters passed in by Iguana: $hostname$ $port$ $channel$ $component$
            const string Usage = "Usage: IGCexample.exe Hostname Port Channel Component";

            try
            {
                if (args.Length != 4)
                {
                    throw new System.Exception("Invalid number of command-line arguments.");
                }

                string Hostname = args[0];
                int Port = System.UInt16.Parse(args[1]);
                string Channel = args[2];
                string Component = args[3];

                if (Component != "destination")
                {
                    throw new System.Exception("Invalid component - only 'destination' is supported by this plugin.");
                }

                // Construct the message processor.
                IGCexampleMain Main = new IGCexampleMain();

                // Attach the event handlers to the processor.
                Main.Processor.OnDisconnect +=
                    new MessageProcessor.IGCmessageProcessorOnDisconnect(Main.DisconnectHandler);
                Main.Processor.OnMessageReceived +=
                    new MessageProcessor.IGCmessageProcessorOnMessageReceived(Main.MessageReceivedHandler);

                // Connect to Iguana. 
                System.Console.WriteLine("Connecting to Iguana");
                Main.Processor.connect(Hostname, Port, Channel, Component);

                // Wait for the stop event, which is generated when the Iguana channel is stopped
                Main.StopEvent.WaitOne();
            }
            catch (iNTERFACEWARE.IGC.Exception Error)
            {
                System.Console.WriteLine(Error.Description);
            }
            catch (System.Exception Error)
            {
                System.Console.WriteLine(Error.Message);
            }
        }
    }
}
