// File: studentDB.java

import java.io.*;

class studentDB {

	/** Holds a container that allows indexing with integers */
	public static Indexable numberDict;
	
	/** Holds a container that allows indexing with strings */
	public static Indexable nameDict;
	
	/**
	 * Test program for testing dictionaries.
	 */
	public static void main(String[] args) {
		String fileName = "";
		String action = "";
				
		// Count num params after file name and action
		int numParams = args.length - 2; 
		
		// Parse the file name and action form teh command line
		if (args.length >= 2) {		
			fileName = args[0];
			action = args[1];
		}
		
		// Perform the corresponding action
		if (numParams == 1 && action.equals("-create")) {
			if (CreateDictionaries(args[2]))
				SaveDictionaries(fileName);
		} 
		else if (numParams == 1 && action.equals("-search")) {
			if (OpenDictionaries(fileName))
				SearchStudent(args[2]);
		}
		else if (numParams == 2 && action.equals("-insert")) {
			if (OpenDictionaries(fileName)) {
				InsertStudent(Integer.parseInt(args[2]), args[3]);
				SaveDictionaries(fileName);
			}
		}
		else if (numParams == 1 && action.equals("-delete")) {
			if (OpenDictionaries(fileName)) {
				DeleteStudent(Integer.parseInt(args[2]));
				SaveDictionaries(fileName);
			}
		}
		else {
			// Wrong cmd line params. Show usage.			
			System.err.println("Usage: progname FILE ACTION PARAMS...\n");
			System.err.println("ACTION & PARAMS:");
			System.err.println("\t-create [RBT or HT]");
			System.err.println("\t-insert NUMBER NAME");
			System.err.println("\t-delete NUMBER");
			System.err.println("\t-search NAME");			
		}				
	}
	
	/** Inserts an student into the currently open dictionaries */
	public static void InsertStudent(int number, String name) {
		Student s = new Student(new Integer(number), name);
		numberDict.insert(s);
		nameDict.insert(s);
	}
	
	/** Delets an student from the currently open dictionaries */
	public static void DeleteStudent(int number) {
		Integer studentNumber = new Integer(number);
		try {
			Student s = (Student)numberDict.delete(studentNumber);	 
			nameDict.delete(s.name);
		} catch (IndexOutOfBoundsException e) {
			// The student is not in the container	
			System.out.println(e.getMessage());
		}	
	}
	
	/** Searches for the student with the given name and prints its info*/
	public static void SearchStudent(String name) {
		Student s = (Student)nameDict.search(name);	
		System.out.println((s == null) ? "Record not found":s.toString());
	}
	
	/** Creates dictionaries implemented by the given ADT */
	public static boolean CreateDictionaries(String typeADT) {
		if (typeADT.equals("RBT")) {
			numberDict = new RecordRBTDictionary();
			nameDict = new StudentNameRBTDictionary();
		}
		else if(typeADT.equals("HT")) {
			System.out.println("Function not implemented");
		}
		else {
			System.err.println("Error: " + typeADT + " is not a valid ADT");
		}
			
		return (numberDict != null && nameDict != null);
	}
	
	/** Reads in the dictionaries (NOTE: the order matters) */
	public static boolean OpenDictionaries(String fileName) {
		numberDict = null;
		nameDict = null;
		
		try {
			FileInputStream fis = new FileInputStream(fileName);
			ObjectInputStream ois = new ObjectInputStream(fis);		
			numberDict = (Indexable)ois.readObject();
			nameDict = (Indexable)ois.readObject();
		} catch (FileNotFoundException e) {
			System.err.println("Create the file before using it. Use -create.");		
		} catch (Exception e) {
			System.err.println(e.getMessage());
		}
		
		return (numberDict != null && nameDict != null);
	}
	
	/** Write down the dictionaries (NOTE: the order matters) */
	public static void SaveDictionaries(String fileName) {	
		try {
			FileOutputStream fos = new FileOutputStream(fileName);
			ObjectOutputStream oos = new ObjectOutputStream(fos);		
			oos.writeObject(numberDict);
			oos.writeObject(nameDict);
		} catch (Exception e) {
			System.err.println("Cannot save object. Msg: " + e.getMessage());
		}
	}
}

