package pp.s1184725.boppi.util;

import java.util.Scanner;
import java.util.logging.Logger;

import org.apache.commons.cli.*;

import pp.iloc.model.Program;
import pp.s1184725.boppi.ToolChain;

/**
 * Provides an interactive command line for Boppi.
 * 
 * @author Frank Wibbelink
 */
public class InteractivePrompt {
	private static CommandLine cmd;
	private static Scanner sc;

	/**
	 * Runs the interactive command line.
	 * 
	 * @param args
	 *            unused
	 */
	public static void main(String[] args) {
		Options options = new Options();
		options.addOption("s", "stateless", false, "run stateless (every command will run in a fresh environment)");
		options.addOption("n", "empty-line", false, "keep reading a single command until the user enters an empty line");
		options.addOption("h", "help", false, "display this message");
		options.addOption("p", "print-program", false, "prints the program before executing it");
		options.addOption("D", "debug", false, "runs a program in debug mode");
		options.addOption("k", "keep", false, "appends every new command to previous input (implies --stateless)");
		
		try {
			cmd = new DefaultParser().parse(options, args);
		}
		catch (ParseException e) {
			System.err.println(e.getLocalizedMessage());
			return;
		}
		
		if (cmd.hasOption("h")) {
			HelpFormatter formatter = new HelpFormatter();
			formatter.printHelp("boppi", "", options, "Exit a program by typing 'exit' on a line.");
			return;
		}

		sc = new Scanner(System.in);
		
		if (cmd.hasOption("n"))
			sc.useDelimiter("\r?\n\r?\n");
		else
			sc.useDelimiter("\r?\n");
		
		if (cmd.hasOption("s") || cmd.hasOption("k"))
			stateless();
		else
			System.err.println("Stateful interactive mode is not supported.");
		
		sc.close();
	}
	
	private static void stateless() {
		Logger logger = Logger.getAnonymousLogger();
		String saved = "";
		while (sc.hasNext()) {
			String command = sc.next().trim();
			
			if(command.equals(""))
				continue;
			
			if (command.equals("exit"))
				break;
			
			String code = saved+command;
			
			if (cmd.hasOption("k"))
				saved = code+";\n";
			
			Program program = ToolChain.compile(ToolChain.getCharStream(code), logger);
			
			if (cmd.hasOption("p")) {
				for (String line : program.prettyPrint().split("\n"))
					System.out.println("--- "+line);
			}
			
			for (String str : ToolChain.execute(program, logger, "").split("\n"))
				System.out.println("<<< "+str);
		}
	}

}
