import java.io.*;
import java.util.*;

public class InteractiveDBTester {
    public static void main(String[] args) {
        // *** Add code for steps 1 - 3 of the main method ***
       
    	CustomerDatabase database = new CustomerDatabase();	//Create database
        Scanner stdin = new Scanner(System.in);  // for reading console input
        String input = null;
        boolean done = false;
        while (!done) {
        	input = stdin.nextLine();
            //Check whether the user entered a file input
            String filepath = input.trim();
            if (input.length() > 1 || !filepath.contains(" ")) {	//If input is > 1 and no spaces, assume it's a file path
            	//Step 2 - Check if the file exists and is readable
            	try {
            		File srcFile = new File(filepath);
            		Scanner fileIn = new Scanner(srcFile);
            		if (!fileIn.hasNext()) {	//If file is empty, display message
            			System.out.println("Error: Cannot access input file");
            			break;
            		}
            		//Otherwise, let's fire up the CustomerDatabase
            		database = new CustomerDatabase();
            		//Step 3 - Load the file
            		while (fileIn.hasNextLine()) {
            			String line = fileIn.nextLine();	//Pull out the line from the file
            			line = line.toLowerCase();	//get everything into lowercase before building database
            			Integer readPoint = line.indexOf(",");	//Find a comma, we can assume there will be at least one
            			String userName = line.substring(0, readPoint);
            			database.addCustomer(userName);	//Add Customer to database
            			String whatsLeft = line.substring(readPoint + 1);
            			while (whatsLeft.contains(","))	{	//Pull out pieces while there are commas left in the line
            				readPoint = whatsLeft.indexOf(",");
            				String product = whatsLeft.substring(0, readPoint);
            				database.addProduct(userName, product);	//Add product to Customer's Wishlist
            				whatsLeft = whatsLeft.substring(readPoint + 1);
            			}
            			database.addProduct(userName, whatsLeft);	//The last product on the line
            		}
            		fileIn.close();
            	} catch (FileNotFoundException exc) {
            		 System.out.println("Error: Cannot access input file");
            	}
            }
            if (database.size() > 0) {
            	done = true;	//If we actually have at least one customer in the database, we can move on
            }
        }
        printOptions();
        done = false;
        while (!done) {
            System.out.print("Enter option ( dfhisqr ): ");
            input = stdin.nextLine();
            input = input.toLowerCase();  // convert input to lower case
            
            // only do something if the user enters at least one character
            if (input.length() > 0) {
                char choice = input.charAt(0);  // strip off option character
                String remainder = "";  // used to hold the remainder of input
                if (input.length() > 1) {
                    // trim off any leading or trailing spaces
                    remainder = input.substring(1).trim();
                }
                //Step 1 - Check whether exactly one command line argument is given
                if (remainder.contains(" ")) {	//If there is another space in the remainder of the input,
                								//we can assume the user tried to enter multiple commands
                	System.out.println("Please provide input file as command-line argument");
                	break;		//Directions say to quit after displaying the message
                }
                if (remainder.equals("d") || remainder.equals("f") || remainder.equals("h") || remainder.equals("i")) {
                	break;		//Check to see if the remainder is the same as a command
                }
                if (remainder.equals("s") || remainder.equals("r") || remainder.equals("q")) {
                	break;		//See above for explanation, split to make more readable
                }
                List<String> wishList;	//A few of the commands need a wishList, will share one variable
                switch (choice) {
                
                case 'd':
                    if (!database.containsProduct(remainder)) {
                    	System.out.println("product not found");
                    }
                    database.removeProduct(remainder);
                    break;


                case 'f':
                    if (!database.containsCustomer(remainder)) {
                    	System.out.println("customer not found");
                    	break;
                    }
                    String display;
                    display = remainder + ":";
                    wishList = database.getProducts(remainder);
                    Iterator<String> strIter = wishList.iterator();
                    while (strIter.hasNext()) {
                		display = display + strIter.next() +  ",";	//Add all products to display line
                    }
                    display = display.substring(0, display.length() - 1);
                    System.out.println(display);
                    break;

                case 'h': 
                    printOptions();
                    break;

                case 'i':
                	Iterator<Customer> iter = database.iterator();
                	Customer cust;
                	Integer prodTotal = 0;
                	Integer maxAvg = 0;
                	Integer minAvg = 0;
                	Integer average = 0;
                	Integer size = 0;
                	List <String> products = new ArrayList<String>();
                	List <Integer> counts = new ArrayList<Integer>();
                	while (iter.hasNext()) {
                		cust = iter.next();
                		wishList = cust.getWishlist();
                		Iterator<String> wishIter = wishList.iterator();
                    	while (wishIter.hasNext()) {
                    		String tempString = wishIter.next();
                    		if (!products.contains(tempString)) {
                    			products.add(tempString);
                    			counts.add(1);
                    		} else {
                    			Integer index = products.indexOf(tempString);
                    			counts.add(index, counts.get(index) + 1);  //Keep track of how much it happens
                    			counts.remove(index + 1);	//We remove original entry if there
                    		}
                    	} 
                		average = wishList.size();
                		if (average > maxAvg) {
                			maxAvg = average;
                		}
                		if (minAvg.equals(0) || average < minAvg) {
                			minAvg = average;
                		}
                		prodTotal = products.size();	//Calculate total number of products
                	}
                	Integer countsIter = 0;
                	Iterator<String> productsIter = products.iterator();
                	Integer maxInt = 0;
                	Integer minInt = 0;
                	String prodTemp = null;
                	while (productsIter.hasNext()) {
                		prodTemp = productsIter.next();
                		Integer countTemp = counts.get(countsIter);
                		if (countTemp > maxInt) {
                			maxInt = countTemp;
                		}
                		if (minInt.equals(0) || countTemp < minInt) {
                			minInt = countTemp;
                		}
                		countsIter = countsIter + 1;
                	}
                	size = database.size();
                	average = prodTotal / size;
                	System.out.println("Customers: " + String.valueOf(size) + " Products: " + String.valueOf(prodTotal));
                	System.out.println("# of products/customer: most " + String.valueOf(maxAvg) + " least "
                			+ String.valueOf(minAvg) + " average " + String.valueOf(average));
                	Integer average2 = size / prodTotal;
                	System.out.println("# of customers/product: most " + String.valueOf(maxInt) + " least "
                			+ String.valueOf(minInt) + " average " + String.valueOf(average2));
                	System.out.println("Most popular product: " + products.get(counts.indexOf(maxInt)) + " [" + maxInt + " ]");
                	break;
                    
                case 's':
                    if (!database.containsProduct(remainder)) {
                    	System.out.println("product not found");
                    	break;
                    }
                    Iterator<Customer> iter2 = database.iterator();
                	Customer cust2;
                	String display2 = null;
                	display2 = remainder + ":";
                	while (iter2.hasNext()) {
                		cust2 = iter2.next();                		
                		if (database.hasProduct(cust2.getUsername(), remainder)) {
                            display2 = display2 + cust2.getUsername() + ",";
                		}    
                	}
                	display2 = display2.substring(0, display2.length() - 1);	//Remove final comma
            		System.out.println(display2);
                    break;

                case 'q':
                    done = true;
                    System.out.println("quit");
                    break;

                case 'r':
                    if (!database.containsCustomer(remainder)) {
                    	System.out.println("customer not found");
                    	break;
                    }
                    database.removeCustomer(remainder);
                    System.out.println("customer removed");
                    break;

                default:  // ignore any unknown commands
                    break;
                }
            }
        }
        
        stdin.close();
    }

    /**
     * Prints the list of command options along with a short description of
     * one.  This method should not be modified.
     */
    private static void printOptions() {
        System.out.println("d <product> - discontinue the given <product>");
        System.out.println("f <customer> - find the given <customer>");
        System.out.println("h - display this help menu");
        System.out.println("i - display information about this customer database");
        System.out.println("s <product> - search for the given <product>");
        System.out.println("q - quit");
        System.out.println("r <customer> - remove the given <customer>");
    }
}