import java.io.*;
import edu.cornell.cs.sam.io.Tokenizer;
import edu.cornell.cs.sam.io.SamTokenizer;
import static edu.cornell.cs.sam.io.SamTokenizer.TokenizerOptions;
import edu.cornell.cs.bali.compiler.*;

public class BC{
	public static void main(String args[]){
		String outFileName;
		int startIndex = 0;
		String output = null;
		String extension = ".sam";
		Tokenizer in;
		CS212Compiler bc;
		
		if(args.length > 3 || args.length < 1) printUsage();
		
		bc = new BaliCompiler();
		try {
			if(args[0].equals("-o")){
				startIndex = 1;
				in = new SamTokenizer(args[1], 
					TokenizerOptions.PROCESS_STRINGS,
					TokenizerOptions.PROCESS_CHARACTERS);

				if(!(bc instanceof CS212OptimizedCompiler)) printUsage();
				output = ((CS212OptimizedCompiler)bc).optimizedCompile(in, null);
			}
			else if(args[0].equals("-b")){
				startIndex = 1;
				in = new SamTokenizer(args[1],
					TokenizerOptions.PROCESS_STRINGS,
					TokenizerOptions.PROCESS_CHARACTERS);

				in = new SamTokenizer(args[1]);
				if(!(bc instanceof CS212CGCompiler)) printUsage();
				output = ((CS212CGCompiler)bc).toBali(in);
				extension = ".cgbali";
			}
			else if(args[0].equals("-a")){
				startIndex = 1;
				in = new SamTokenizer(args[1],
					TokenizerOptions.PROCESS_STRINGS,
					TokenizerOptions.PROCESS_CHARACTERS);

				if(!(bc instanceof CS212TreeCompiler)) printUsage();
				((CS212TreeCompiler)bc).viewTree(in);
			}
			else if (args.length == 3) printUsage();
			else { 
				in = new SamTokenizer(args[0],
					TokenizerOptions.PROCESS_STRINGS,
					TokenizerOptions.PROCESS_CHARACTERS);

				output = bc.compile(in);
			}
	
		}
		catch(IOException e){
			System.out.println("I/O Error reading file: " + e.getMessage());
			return;
		}
		catch (IllegalBaliException e) {
			System.out.println(e.toString());
			return;
		}

		if (output != null) {
                        if(args.length == startIndex+2)
                                outFileName = args[startIndex+1];
                        else if(args[startIndex].indexOf(".") < 0)
                                outFileName = args[startIndex] + extension;
                        else
                                outFileName = args[startIndex].substring(0, args[startIndex].lastIndexOf(".")) + extension;
                        try{
                                BufferedWriter out = new BufferedWriter(new FileWriter(outFileName));
                                out.write(output);
                                out.close();
                        }
                        catch(IOException e){
                                System.out.println("I/O Error writing output: " + e.getMessage());
                                System.exit(0);
                        }	
		}
	}
  
	public static void printUsage(){
		System.out.println("Bali++ Compiler");
		System.out.println("---------------");
		System.out.println("");
		System.out.println("Usage: java BC [-o | -b | -a] <inputfile> [<outputfile>]");
		System.out.println("");
		System.out.println("Parameters:");
		System.out.println("-o: Enable optimizations");
		System.out.println("-b: Output Bali++ translation");
		System.out.println("-a: Display AST in graphical window");
		System.out.println("");
		System.out.println("This compiler supports the following features:");
		CS212Compiler bc = new BaliCompiler();
		if(bc instanceof CS212OptimizedCompiler) System.out.println("Optimization");
		if(bc instanceof CS212TreeCompiler) System.out.println("Graphical AST Display");
		if(bc instanceof CS212CGCompiler) System.out.println("Bali++ Output");
		System.out.println("SaM Output");
		System.exit(1);
	}
}
