package server;

import javax.swing.JOptionPane;
import java.rmi.RMISecurityManager;
import gui.*;

public class Main {
	
	final private static String helpMessage = "Executes the Connect Four Database Server with the specified input parameters.\n\n" +
											  "usage: java server.Main [-rmi ext/int] [-rmiport 1099] [-dblist \"dbms.cfg\"]\n\n" +
											  " -rmi :: specifies how to run rmi, either [ext]ernal or [int]ernal; e.g., -rmi int\n" +
											  "         (if left unspecified, will default to internal)\n" +
											  " -rmiport :: specifies which port to use for rmi; e.g., -rmiport 1099\n" +
											  "             (if no port is specified, defaults to 1099)\n" +
											  " -dblist :: indicates which config file the database should use; e.g., -dblist \"dbms.cfg\"\n" +
											  "        (if left unspecified, will default to \"dbms.cfg\")\n" +
											  " -dbms :: indicates which dbms should be used; e.g., -dbms \"SQLite\"\n" +
											  "        (if left unspecified, will prompt for dbms or load dbms if only 1 in list)";
	
	public static void main(String[] args) {
		// pre-configure the policy file and install the security manager
		System.setProperty("java.security.policy", "all.policy");
		System.setSecurityManager(new RMISecurityManager());
		
		// parse input parameters
		parseParameters(args);
	}
	
	public static void displayHelp() {
		// print instructions on how to use program parameters
		JOptionPane.showMessageDialog(null, helpMessage, "Help", JOptionPane.INFORMATION_MESSAGE);
	}
	
	public static void parseParameters(String[] args) {
		// verify that there is a correct number of arguments
		if(args != null && args.length % 2 != 0) {
			displayHelp();
			return;
		}
		
		boolean integratedRegistry = true;
		int registryPort = 1099;
		String databaseConfigFileName = null;
		String dbmsName = null;
		
		// parse program arguments
		if(args != null) {
			for(int i=0;i<args.length;i+=2) {
				// parse rmi type
				if(args[i].equalsIgnoreCase("-rmi")) {
					String temp = args[i+1];
					if(temp == null) {
						JOptionPane.showMessageDialog(null, "Registry type cannot be null.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
					if(temp.startsWith("int")) {
						integratedRegistry = true;
					}
					else if(temp.startsWith("ext")) {
						integratedRegistry = false;
					}
					else {
						JOptionPane.showMessageDialog(null, "Registry type can only be either int or ext.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
				}
				// parse rmi port
				else if(args[i].equalsIgnoreCase("-rmiport")) {
					String temp = args[i+1];
					if(temp == null) {
						JOptionPane.showMessageDialog(null, "Registry port cannot be null.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
					int port = -1;
					try { port = Integer.parseInt(temp); }
					catch(NumberFormatException e) { }
					if(port < 1 || port > 65535) {
						JOptionPane.showMessageDialog(null, "Registry port must be between 1 and 65535.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
					registryPort = port;
				}
				// parse dbms list file name
				else if(args[i].equalsIgnoreCase("-dblist")) {
					String temp = args[i+1];
					if(temp == null) {
						JOptionPane.showMessageDialog(null, "Database configuration filename cannot be null.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
					databaseConfigFileName = temp.trim();
					if(databaseConfigFileName.length() == 0) {
						JOptionPane.showMessageDialog(null, "Database configuration filename cannot be empty.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
				}
				// parse dbms name
				else if(args[i].equalsIgnoreCase("-dbms")) {
					String temp = args[i+1];
					if(temp == null) {
						JOptionPane.showMessageDialog(null, "Database management system name cannot be null.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
					dbmsName = temp.trim();
					if(dbmsName.length() == 0) {
						JOptionPane.showMessageDialog(null, "Database managment system name cannot be empty.", "Invalid Argument", JOptionPane.ERROR_MESSAGE);
						displayHelp();
						return;
					}
				}
				// handle invalid arguments
				else {
					JOptionPane.showMessageDialog(null, "Invalid argument: " + args[i], "Invalid Argument", JOptionPane.ERROR_MESSAGE);
					displayHelp();
					return;
				}
			}
		}
		
		// initialize the dbms window
		DatabaseWindow window = new DatabaseWindow();
		window.initialize(databaseConfigFileName, dbmsName, integratedRegistry, registryPort);
	}
	
}
