using System;
using System.IO;
using System.Linq;
using System.Timers;
using System.Threading;
using System.ServiceProcess;
using System.Collections.Generic;

using FilterAPI;
using FilterAPI.Networking;

using FilterManager.LocalHandlers;
using FilterManager.LocalNetworking;

using FilterManager.ManagerHandlers;
using FilterManager.ManagerNetworking;

namespace FilterManager
{
    public partial class Service : ServiceBase
    {
        private Boolean DBsIDSyncIsDone = true;
        private Boolean PingIsDone = true;

        public Service() { }

		internal void Init()
		{
			AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

			Program.Auth = new Authentication();
			Program.SQL = new Database(Program.Auth);
			Program.SQL.WipetLoggedInChars();
			Program.SQL.WipetParties();

			Program.LocalHandlers = new LocalHandlerLoader();
			Program.LocalClient = new LocalClient();

			Program.LoadSHNs();

			ManagerListener MListen = new ManagerListener();

			Program.ManagerHandlers = new ManagerHandlerLoader();

			if (true == true)
			{
				Thread NewThread = new Thread(delegate ()
				{
					while (true)
					{
						if (DBsIDSyncIsDone) { RunDBsIDSync(); }

						Thread.Sleep(3000);
					}
				});

				NewThread.Start();
			}

			if (true == true)
			{
				Thread NewThread = new Thread(delegate ()
				{
					while (true)
					{
						if (PingIsDone) { RunPing(); }

						Thread.Sleep(5000);
					}
				});

				NewThread.Start();
			}
		}

        protected override void OnStart(String[] Args)
        {
			Init();
        }

        private void RunDBsIDSync()
        {
            DBsIDSyncIsDone = false;

            try
            {
                List<String> sIDs = Program.SQL.GetOnlinesIDs();

                foreach (ManagerClient MClient in Program.ManagerClients.Values.Where(sID => sID.sID != String.Empty))
                {
                    if (!sIDs.Contains(MClient.sID)) { Program.SQL.InserttLoggedInChar(MClient.sID); }
                }

                foreach (String sID in sIDs)
                {
                    if (Program.ManagerClients.Values.Where(OnlinesID => OnlinesID.sID == sID).FirstOrDefault() == null) { Program.SQL.DeleteFromtLoggedInChar(sID); }
                }
            }
            catch (Exception Error) { Program.SendConsoleText(ConsoleColor.Red, "Manager error - DB sID sync\n{0}", Error.ToString()); }

            DBsIDSyncIsDone = true;
        }

        private void RunPing()
        {
            PingIsDone = false;

            try
            {
                using (var ServerPacket = new Packet(2, 4))
                {
                    foreach (ManagerClient MClient in Program.ManagerClients.Values) { MClient.SendPacketClient(ServerPacket); }

                    Thread.Sleep(1000);
                }
            }
            catch (Exception Error) { Program.SendConsoleText(ConsoleColor.Red, "Manager error - Ping\n{0}", Error.ToString()); }

            PingIsDone = true;
        }

        private void CurrentDomain_UnhandledException(Object Sender, UnhandledExceptionEventArgs Args)
        {
            File.WriteAllLines(String.Format("{0}{1}Crash.txt", AppDomain.CurrentDomain.BaseDirectory, AppDomain.CurrentDomain.FriendlyName.Replace(".exe", "")), new String[] { ((Exception)Args.ExceptionObject).ToString() });

            Program.SendConsoleText(ConsoleColor.Red, ((Exception)Args.ExceptionObject).ToString());
        }

        protected override void OnStop() { }
    }
}
