package metalexer.metalexer;

import java.io.*;

import junit.framework.TestCase;
import metalexer.Constants;

public class PrettyPrinterIdentityTests extends TestCase {
    private static final String TEST_DIR = "test/backend-metalexer/";
    private static final String IN_DIR = TEST_DIR + "in/";
    private static final String OUT1_DIR = TEST_DIR + "out1/";
    private static final String OUT2_DIR = TEST_DIR + "out2/";

    private static final FilenameFilter METALEXER_FILE_FILTER = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            return name.endsWith(Constants.LAYOUT_FILE_EXT) || name.endsWith(Constants.COMPONENT_FILE_EXT);
        }
    };

    public void test_metalexer_component() throws Exception {
        checkLayout("metalexer", "component");
    }

    public void test_metalexer_layout() throws Exception {
        checkLayout("metalexer", "layout");
    }

    public void test_natlab_natlab() throws Exception {
        checkLayout("natlab", "natlab");
    }

    public void test_natlab_annotations() throws Exception {
        checkLayout("natlab", "annotations");
    }

    public void test_natlab_annotated_natlab() throws Exception {
        checkLayout("natlab", "annotated_natlab");
    }

    public void test_natlab_attributed_natlab() throws Exception {
        checkLayout("natlab", "attributed_natlab");
    }

    public void test_natlab_naive_natlab() throws Exception {
        checkLayout("natlab-naive", "natlab");
    }

    private static void checkLayout(final String dirName, final String layoutName) throws IOException {
        ML2ML.main(new String[]{layoutName, IN_DIR + dirName, OUT1_DIR + dirName + "/" + layoutName});
        ML2ML.main(new String[]{layoutName, OUT1_DIR + dirName + "/" + layoutName, OUT2_DIR + dirName + "/" + layoutName});
        assertBitwiseEquals(OUT1_DIR + dirName + "/" + layoutName, OUT2_DIR + dirName + "/" + layoutName);
    }

    private static void assertBitwiseEquals(String out1DirName, String out2DirName) throws IOException {
        File[] out1Files = new File(out1DirName).listFiles(METALEXER_FILE_FILTER);
        assertNotNull("Files in out1", out1Files);
        File[] out2Files = new File(out2DirName).listFiles(METALEXER_FILE_FILTER);
        assertNotNull("Files in out2", out2Files);
        assertEquals("Number of files", out1Files.length, out2Files.length);
        for(int i = 0; i < out1Files.length; i++) {
            assertEquals("File names", out1Files[i].getName(), out2Files[i].getName());
            assertBitwiseEquals(out1Files[i], out2Files[i]);
        }
    }

    private static void assertBitwiseEquals(File file1, File file2) throws IOException {
        BufferedReader in1 = new BufferedReader(new FileReader(file1));
        BufferedReader in2 = new BufferedReader(new FileReader(file2));
        while(true) {
            int ch1 = in1.read();
            int ch2 = in2.read();
            assertEquals(file1.getName(), ch1, ch2);
            if(ch1 < 0) {
                break;
            }
        }
    }
}
