using System;
using System.Runtime.Remoting.Channels;
using System.Threading;
using Ch.Elca.Iiop;
using Ch.Elca.Iiop.Services;
using System.Diagnostics;
using System.Runtime.Remoting;
using IIOPLib;

public class MathImpl : MarshalByRefObject, MathModule.Math
{
    public override object InitializeLifetimeService()
    {
        return null;  // live forever
    }

    public int Add(int x, int y)
    {
        return x + y;
    }
}

public class CSServerIIOP
{
    static int _orbInitialPort = 0;
    static string _orbInitialHost = "localhost";

    public static bool ParseArgs(string[] args)
    {
        try
        {
            int orbInitialPortIndex = Array.IndexOf(args, "-ORBInitialPort");
            int orbInitialHostIndex = Array.IndexOf(args, "-ORBInitialHost");

            if (
                // have -? or -help
                (Array.IndexOf(args, "-help") != -1) ||
                (Array.IndexOf(args, "-?") != -1) ||
                // missing -ORBInitialPort
                (orbInitialPortIndex == -1)
                )
            {
                Console.WriteLine("-? -help                  print this message");
                Console.WriteLine("-ORBInitialPort <port>    nameserver port (required)");
                Console.WriteLine("-ORBInitialHost <host>    nameserver host");
                return false;
            }

            if (args.Length > orbInitialPortIndex + 1)
                _orbInitialPort = Convert.ToInt32(args[orbInitialPortIndex + 1]);
            if ((orbInitialHostIndex != -1) && (args.Length > orbInitialHostIndex + 1))
                _orbInitialHost = args[orbInitialHostIndex + 1];
            return true;
        }
        catch (Exception e)
        {
            Console.WriteLine("Failed to parse arguments: " + e.Message);
            return false;
        }
    }



    public static void Main(string[] args)
    {
        try
        {
            if (!ParseArgs(args))
                return;

            CorbaInit init = CorbaInit.GetInit();

            // initialize the channel
            IiopChannel channel = new IiopChannel(0);
            ChannelServices.RegisterChannel(channel, false);

            // create the Math servant
            MathImpl math = new MathImpl();
            string objectURI = "math";
            RemotingServices.Marshal(math, objectURI);

            Naming naming = new Naming(_orbInitialHost, _orbInitialPort);
            String instanceName = "CSI_" + Process.GetCurrentProcess().Id + "@" + Environment.MachineName;
            Ref r = new Ref(instanceName, math);
            naming.Bind(init, r);

            Semaphore s = new Semaphore(0, 1);
            Console.CancelKeyPress +=
                new ConsoleCancelEventHandler(
                    (object obj, ConsoleCancelEventArgs e) =>
                    {
                        e.Cancel = true;
                        Console.WriteLine("Shutting down...");
                        s.Release();
                    });

            Console.WriteLine("Running " + instanceName);
            s.WaitOne();

            naming.Unbind(init, r);
        }
        catch (Exception e)
        {
            Console.WriteLine("Exception: " + e);
        }
    }
}
