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

using System;
using System.IO;
using System.Net;

using Microsoft.Win32;

namespace EA.GameTalkConfig
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary>
	class GameTalkConfig
	{
		enum OutputFormat
		{
			Header,
			Cpp,
			Data
		}

		#region File Content Format

		private static readonly string mCppFormat =
			@"
/*
    Copyright 2004-2005 Electronic Arts Inc.

	This file is auto-generated by GameTalkConfig.exe
*/

// Ip Address of the GameTalkServer on the user's machine (Ip address of the PC)
const char* gGameTalkServerIpAddress = ""{0}"";

// The port to connect to
int gGameTalkServerPort = {1};

";

		private static readonly string mHeaderFormat =
@"
/*
    Copyright 2004-2005 Electronic Arts Inc.

	This file is auto-generated by GameTalkConfig.exe
*/

// --- Include guard

#ifndef EA_GAMETALK_GAMETALKCONFIG_H
#define EA_GAMETALK_GAMETALKCONFIG_H

// Ip Address of the GameTalkServer on the user's machine (Ip address of the PC)
const char* const gGameTalkServerIpAddress = ""{0}"";

// The port to connect to
const int gGameTalkServerPort = {1};


#endif // EA_GAMETALK_GAMETALKCONFIG_H
";

		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main(string[] args)
		{
			if (args.Length == 2)
			{
				switch (args[0].ToLower())
				{
					case "-cpp":
						CreateCppFile(args[1]);
						break;
					case "-header":
						CreateHeaderFile(args[1]);
						break;
					case "-data":
						CreateDataFile(args[1]);
						break;
				}
			}
			else
			{
				Console.WriteLine("    Invalid arguments.");
				Console.WriteLine("");
				Console.WriteLine("    GameTalkConfig Help:");
				Console.WriteLine("    Usage:");
				Console.WriteLine("        GameTalkConfig.exe <command> <file name>");
				Console.WriteLine("");
				Console.WriteLine("    Commands:");
				Console.WriteLine("        -cpp		   Will create a cpp file.");
				Console.WriteLine("        -header     Will create a header file.");
				Console.WriteLine("        -data       Will create a text data file.");
				Console.WriteLine("");
				Console.WriteLine("    file name:");
				Console.WriteLine("        Specify the file name and path to be generated.");
			}
		}
		
		static private void CreateDataFile(string fileName)
		{
			fileName = Path.GetFullPath(fileName);

			string newFileContent = CreateDataContent();
			string currentFileContent = FileIO.ReadFileContent(fileName);

			if (!currentFileContent.Equals(newFileContent))
			{
				Console.WriteLine(string.Format("Generating new {0}.", fileName));
				FileIO.WriteFileContent(fileName, newFileContent);
			}
		}

		static private string CreateDataContent()
		{
			string newFileContent = string.Empty;

			try
			{
				string ipAddress = GetIpAddress();
				int port = 9876;
				try
				{
					string keyName = @"Software\Electronic Arts Inc.\GameTalkServer";
					RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName);
					port = (int)key.GetValue("Port");
					key.Close();
				}
				catch {}
				newFileContent = ipAddress + Environment.NewLine;
				newFileContent += port.ToString() + Environment.NewLine;
			}
			catch {}

			return newFileContent;
		}
		
		static private void CreateCppFile(string fileName)
		{
			fileName = Path.GetFullPath(fileName);

			string newFileContent = CreateCppContent();
			string currentFileContent = FileIO.ReadFileContent(fileName);

			if (!currentFileContent.Equals(newFileContent))
			{
				Console.WriteLine(string.Format("Generating new {0}.", fileName));
				FileIO.WriteFileContent(fileName, newFileContent);
			}
		}

		static private string CreateCppContent()
		{
			string newFileContent = string.Empty;

			try
			{
				string ipAddress = GetIpAddress();
				int port = 9876;
				try
				{
					string keyName = @"Software\Electronic Arts Inc.\GameTalkServer";
					RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName);
					port = (int)key.GetValue("Port");
					key.Close();
				}
				catch {}
				newFileContent = string.Format(mCppFormat, ipAddress, port);
			}
			catch {}

			return newFileContent;
		}
		
		static private void CreateHeaderFile(string fileName)
		{
			fileName = Path.GetFullPath(fileName);

			string newFileContent = CreateHeaderContent();
			string currentFileContent = FileIO.ReadFileContent(fileName);

			if (!currentFileContent.Equals(newFileContent))
			{
				Console.WriteLine(string.Format("Generating new {0}.", fileName));
				FileIO.WriteFileContent(fileName, newFileContent);
			}
		}

		static private string CreateHeaderContent()
		{
			string newFileContent = string.Empty;

			try
			{
				string ipAddress = GetIpAddress();
				int port = 9876;
				try
				{
					string keyName = @"Software\Electronic Arts Inc.\GameTalkServer";
					RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName);
					port = (int)key.GetValue("Port");
					key.Close();
				}
				catch {}
				newFileContent = string.Format(mHeaderFormat, ipAddress, port);
			}
			catch {}

			return newFileContent;
		}

		/// <summary>
		/// Convert a Dns name to an ip address.
		/// </summary>
		/// <returns>The ip address if resolved otherwise the host name is returned.</returns>
		static private string GetIpAddress()
		{
			string hostName = Dns.GetHostName();
			string ipAddress = "0.0.0.0";

			try
			{
				// Then using host name, get the IP address list..
				// Important that we use Dns.GetHostAddresses instead of Dns.GetHostEntry - since if you give GetHostEntry
				// an IP address it can attempt a reverse look-up and end up with a host name that was unintended - this
				// only comes up once in a blue moon - but GetHostEntry will get the wrong address list if it is handed a raw IP address
                IPAddress[] addressList = Dns.GetHostAddresses(hostName);
                foreach(IPAddress hostAddress in addressList)
                {
                    // Make sure to get the IPv4 address and not the IPv6 address.
                    if(hostAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        ipAddress = hostAddress.ToString();
                        break;
                    }
                }
			}
			catch
			{
			}

			return ipAddress;
		}
	}
}
