using System;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;

namespace edu.jhu.Cas.Service {
	/*
	 * Handles all service-specfic stuff.
	 */
	public class CJobsService:ServiceBase {
		private System.ComponentModel.Container components = null;
        private CJobsDBThread
            rjt = new RunJobsThread(),
            cjt = new CancelJobsThread(),
            ot = new OutputThread(),
            mt = new JobCleanThread(),
            oct = new OutputCleanupThread();
		public static bool asService = true;
        public static int MODE;
        public const int JOBS = 0, OUTPUT = 1, BOTH = 2;
         
		public CJobsService() {
		}
		public static void Main(string[] args) {
            MODE = BOTH;
            if (args.Length > 0)
                asService = false;
            Run();
        }
        public static void Run() {
            if (asService) {
                System.ServiceProcess.ServiceBase[] ServicesToRun;
                ServicesToRun = new System.ServiceProcess.ServiceBase[] { new CJobsService() };
                System.ServiceProcess.ServiceBase.Run(ServicesToRun);
            }else {
                Console.Out.WriteLine("Running from command line");
                CJobsService p = new CJobsService();
                CJobsService.asService = false;
                p.OnStart(null);
            }
        }
		
		protected override void OnStart(string[] args) {
            string mode = System.Configuration.ConfigurationSettings.AppSettings["ServiceMode"];
            if (mode == null || mode.Length <= 0)
                throw new Exception("ServiceMode must be specified");
            MODE = int.Parse(mode.Trim());
            if (MODE == JOBS || MODE == BOTH) {
                rjt.StartThread();
                Log("Jobs service started", EventLogEntryType.Information);
                cjt.StartThread();
                Log("Cancel service started", EventLogEntryType.Information);
                mt.StartThread();
                Log("QuickJobCleanup service started", EventLogEntryType.Information);
            }
            if (MODE == OUTPUT || MODE == BOTH) {
                ot.StartThread();
                Log("Output service started", EventLogEntryType.Information);
                oct.StartThread();
                Log("Output cleanup service started", EventLogEntryType.Information);
            }
            return;
        }
		protected override void OnStop() {
			rjt.HaltThread();
		}
		protected override void Dispose( bool disposing ) {
			if( disposing ) {
				if (components != null) {
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
        public static void Log(string s, EventLogEntryType et) {
            try {
                if (CJobsService.asService) {
                    if (!EventLog.SourceExists("CasJobs")) {
                        EventLog.CreateEventSource("CasJobs", "CasJobsServiceLog");
                    }
                    EventLog.WriteEntry("CasJobs", s,
                        et, 234);
                }
                else {
                    Console.WriteLine(s);
                }
            }
            catch { }//good god there better be nothing to catch
        }
	}
}
