using System.Timers;
using System;
using Topshelf;

// see http://docs.topshelf-project.com/en/latest/overview/commandline.html
// > csservice install --sudo
// start stop uninstall

namespace CSService
{
    using System;
    using System.IO;
    using System.Diagnostics;
    using System.Threading.Tasks;
    using com.ociweb.JavaAddLib;
    using log4net.Config;
    using System.Configuration;


    public class CSService
    {
        AddServer _s = new AddServer();
        Task _serviceTask = null;

        public void Start()
        {
            log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));
            try
            {
                String instanceName = "CSS_" + Process.GetCurrentProcess().Id + "@" + Environment.MachineName;
                string namingServerHost = ConfigurationManager.AppSettings["NamingServerHost"];
                int namingServerPort = Convert.ToInt32(ConfigurationManager.AppSettings["NamingServerPort"]);

                log.Info("Starting " + instanceName + " with Naming Service at " + namingServerHost + ":" + namingServerPort);
                _s.init(namingServerPort, namingServerHost);

                // do this in its own thread as Start() needs to terminate quickly
                _serviceTask = Task.Factory.StartNew(() =>
                {
                    try
                    {
                        _s.run(instanceName);
                    }
                    catch (Exception e)
                    {
                        log.Error("run() failed", e);
                    }
                }
                );  
            }
            catch (Exception e)
            {
                log.Error("Start() failed", e);
            }
        }


        public void Stop()
        {
            if (_s != null)
                _s.shutdown();
            // wait max 10 seconds for the orb run thread to terminate
            if (_serviceTask != null)
                _serviceTask.Wait(10 * 1000); 
        }
    }



    public class Program
    {
        public static void Main()
        {
            // event log must be created by an administrative user, but once created, anyone can use it
            // http://logging.apache.org/log4net/release/faq.html#trouble-EventLog

            // http://stackoverflow.com/questions/6523252/log4net-doesnt-log-in-windows-event-viewer
            // http://www.codeproject.com/Articles/140911/log4net-Tutorial

            XmlConfigurator.Configure();
            log4net.ILog log = log4net.LogManager.GetLogger(typeof(Program));

            try
            {
                CSService svc = new CSService();

                HostFactory.New(x =>
                {
                    x.Service<CSService>(s =>
                    {
                        s.ConstructUsing(name => svc);
                        s.WhenStarted(t => t.Start());
                        s.WhenStopped(t => t.Stop());
                    });
                    x.RunAsLocalSystem();
                    x.StartAutomatically();  

                    x.DependsOnEventLog();
                    x.UseLog4Net();

                    x.SetDescription("CSService service");
                    x.SetDisplayName("CSService");
                    x.SetServiceName("CSService");

                    x.AfterInstall(() => log.Info("CSService installed"));  // will create event log if run as administrator if missing
                    x.AfterUninstall(() => log.Info("CSService uninstalled"));
                }).Run();
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }
    }
}

