import java.io.*;

public class Suite {

    public Suite() { }

    public void goFail() throws Exception {
	 String path = "../l3_test_suite/comperr/";
	File testdir = new File(path);
	File[] files = testdir.listFiles();
	int i;

	for (i = 0; i < files.length; i++) {
	    if (files[i].isDirectory()) continue;
	    String fname = files[i].getName();
	    if (!fname.endsWith("l3")) continue;
	    String ftest = getRootName(fname);
	    Runtime rt = Runtime.getRuntime();
	    System.out.println(ftest);
	    String execcmd = "java -mx64m -ss64m -jar l3.jar -win -o bin/" + ftest + ".s " + path+ftest + ".l3";
	    int cval = rt.exec(execcmd).waitFor();
	    if (cval >= 0) {
		System.out.println("Test Failed"); continue; }
	}

    }

    public void goRunFail() throws Exception {
	String path = "../l3_test_suite/runerr/";
	File testdir = new File(path);
	File[] files = testdir.listFiles();
	int i;

	for (i = 0; i < files.length; i++) {
	    if (files[i].isDirectory()) continue;
	    String fname = files[i].getName();
	    if (!fname.endsWith("l3")) continue;
	    String ftest = getRootName(fname);
	    Runtime rt = Runtime.getRuntime();
	    System.out.println(ftest);
	    String execcmd = "java -mx64m -ss64m -jar l3.jar -win -o bin/" + ftest + ".s " + path+ftest + ".l3";
	    int cval = rt.exec(execcmd).waitFor();
	    if (cval < 0) {
		System.out.println("Compile Failed"); continue; }
	
	    execcmd = "gcc -c -o bin/" + ftest + ".o  bin/" + ftest + ".s";
	    rt.exec(execcmd).waitFor();
	    execcmd = "gcc -o bin/out -L./bin bin/" + ftest + ".o -ll3 -lgc";
	    rt.exec(execcmd).waitFor();
	    execcmd = "bin/out";
	    Process proc = rt.exec(execcmd);
	    int retval = proc.waitFor();
	    if (retval >= 0)
		System.out.println("Test Failed");
	    
	}
	
    }

    private String readStream(InputStream is) throws Exception {
	int c;
	ResultReaderEx reader = new ResultReaderEx();
	
	reader.startReading(is);
	return reader.endReading().toString();
    }

    private String readStream(InputStream is, Process p) throws Exception {
	int c;
	ResultReaderEx reader = new ResultReaderEx();
	
	reader.startReading(is);
	p.waitFor();
	return reader.endReading().toString();
    }

    public void goCorrect() throws Exception {
	String path = "../l3_test_suite/correct/";
	File testdir = new File(path);
	File[] files = testdir.listFiles();
	int i;

	for (i = 0; i < files.length; i++) {
	    if (files[i].isDirectory()) continue;
	    String fname = files[i].getName();
	    if (!fname.endsWith("l3")) continue;
	    String ftest = getRootName(fname);
	    Runtime rt = Runtime.getRuntime();
	    System.out.println(ftest);
	    String execcmd = "java -mx64m -ss64m -jar l3.jar -win -o bin/" + ftest + ".s " + path+ftest + ".l3";
	    int cval = rt.exec(execcmd).waitFor();
	    if (cval < 0) {
		System.out.println("Compile Failed"); continue; }
	
	    execcmd = "gcc -c -o bin/" + ftest + ".o  bin/" + ftest + ".s";
	    rt.exec(execcmd).waitFor();
	    execcmd = "gcc -o bin/out -L./bin bin/" + ftest + ".o -ll3 -lgc";
	    rt.exec(execcmd).waitFor();
	    execcmd = "bin/out";
	    Process proc = rt.exec(execcmd);
	    String output = readStream(proc.getInputStream(), proc);
	    String corval = readResult(path+ftest);
	    if (!output.equals(corval))
		System.out.println("Failed: " + ftest + " R: " + output + " C: " + corval);
	    
	}
	
    }

    private String readResult(String fname) throws Exception {

	String ffile = fname + ".output";
	InputStream file = new FileInputStream(ffile);
	int c;
	String data="";
	while (0 <= (c = file.read())) {
	    data += new Character((char)c);
	}
	return data;
    }

    private String getRootName(String filename) {
	int dotIndex = filename.lastIndexOf('.');
        return filename.substring(0,dotIndex);
    }

    public static void main(String[] args) throws Exception {
	if (args[0].equals("correct"))
	    (new Suite()).goCorrect();
	else if (args[0].equals("comperr"))
	    (new Suite()).goFail();
	else
	    (new Suite()).goRunFail();
    }

}
