// (c) 2005 Electronic Arts Inc.
//

using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.ServiceProcess;
using System.Threading;

using Microsoft.Win32;

using EA.GameTalkRouter;
using EA.GameTalkMessages;

namespace EA.GameTalkServer
{
	public class GameServer : System.ServiceProcess.ServiceBase
	{
		private TcpServer mTcpServer = null;

		public GameServer()
		{
			InitializeComponent();
		}

		// The main entry point for the process
		public static void Main(string [] commandLineArgs)
		{
			//AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
			if (commandLineArgs.Length > 0)
			{
				try
				{
					if (commandLineArgs[0] == EA.GameTalkMessages.Configuration.RunServerAsAppCommandLineArgs)
					{
						EA.GameTalkMessages.RegistrySettings.SetRegistryKeyAreaToCurrentUser();
						System.Windows.Forms.Application.Run(new GameServerConsole());
					}
				}
				catch
				{
					// Could try handling this - but whatever
					throw;
				}
			}
			else
			{
				System.ServiceProcess.ServiceBase[] servicesToRun;
	
				// More than one user Service may run within the same process. To add
				// another service to this process, change the following line to
				// create a second service object. For example,
				//
				//   ServicesToRun = new System.ServiceProcess.ServiceBase[] {new GameServer(), new MySecondUserService()};
				//
				servicesToRun = new System.ServiceProcess.ServiceBase[] { new GameServer() };

				System.ServiceProcess.ServiceBase.Run(servicesToRun);
			}
		}

		// Handy for debugging dll loading issues
		/*static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
		{
			string desired = args.Name;
			string desiredWithCommaDelimiter = args.Name + ",";
			int indexOfComma = args.Name.IndexOf(',');
			if (indexOfComma != -1)
			{
				desired = args.Name.Substring(0, indexOfComma);
				desiredWithCommaDelimiter = args.Name.Substring(0, indexOfComma + 1);
			}

			System.Reflection.Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; i < assemblies.Length; i++)
			{
				if (assemblies[i].FullName.StartsWith(desiredWithCommaDelimiter))
				{
					return assemblies[i];
				}
			}

			System.Diagnostics.Trace.WriteLine("about to return null for: " + desired);

			return null;
		}*/

		public static int GetOrSetPortNumInRegistry()
		{
			bool portSpecifiedInConfiguration = false;
			int port = TcpServer.mDefaultPort;

			int configuredPort = Configuration.Instance.GetGameTalkServerPortNum();
			if (configuredPort >= 0)
			{
				Trace.WriteLine("TcpServer: Port num read from configuration: " + configuredPort);
				port = configuredPort;
				portSpecifiedInConfiguration = true;
				Trace.WriteLine("TcpServer: Successfully retrieved the port number for the GameTalkRouter");
			}
			else
				Trace.WriteLine("TcpServer: failed to retrieve the port number for the GameTalkRouter");

			if (!portSpecifiedInConfiguration)
			{
				Trace.WriteLine("TcpServer: mDefaultPort: " + TcpServer.mDefaultPort);
				if (!Configuration.Instance.SetGameTalkServerPortNum(TcpServer.mDefaultPort))
					Trace.WriteLine("TcpServer: failed to set the port number of the GameTalkRouter");
			}

			return port;
		}

		/// <summary>
		/// Set things in motion so your service can do its work.
		/// </summary>
		protected override void OnStart(string[] args)
		{
			// Call base class
			base.OnStart(args);

			int port = GetOrSetPortNumInRegistry();
			mTcpServer = new GameTalkTcpServer(port);
			mTcpServer.StartServer();
		}
 
		/// <summary>
		/// Stop this service.
		/// </summary>
		protected override void OnStop()
		{
			if (mTcpServer != null)
				mTcpServer.Shutdown();

			// Call base class
			base.OnStop();
		}

		private void InitializeComponent()
		{
			// 
			// GameServer
			// 
			this.ServiceName = "GameServer";

		}
	}
}
