package com.fivetran.javac;

import com.sun.source.tree.CompilationUnitTree;
import com.sun.source.util.JavacTask;
import com.sun.tools.javac.comp.CompileStates;
import org.junit.Ignore;
import org.junit.Test;

import javax.tools.DiagnosticCollector;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Duration;
import java.util.logging.Logger;

import static org.junit.Assert.assertNotNull;

@Ignore
public class CompilerProfiling extends Fixtures {
    private static final Logger LOG = Logger.getLogger("");

    @Test
    public void parsingSpeed() throws IOException, URISyntaxException {
        StringFileObject file = fromResource("/LargeFile.java");

        for (int i = 0; i < 10; i++) {
            Duration duration = compileLargeFile(file);

            LOG.info(duration.toString());
        }
    }

    private Duration compileLargeFile(StringFileObject file) {
        long start = System.nanoTime();

        DiagnosticCollector<JavaFileObject> errors = new DiagnosticCollector<>();
        GetCompilationUnit compilationUnit = new GetCompilationUnit();
        JavacTask task = JavacTaskBuilder.create()
                                         .addFile(file)
                                         .afterParse(compilationUnit)
                                         .reportErrors(errors)
                                         .stopIfError(CompileStates.CompileState.ENTER)
                                         .stopIfNoError(CompileStates.CompileState.ENTER)
                                         .build();

        try {
            task.call();
        } catch (RuntimeException e) {
            if (e.getCause() instanceof AbortCompilation)
                LOG.info("Aborted further stages");
            else
                throw e;
        }

        long finish = System.nanoTime();

        assertNotNull(compilationUnit.result);

        return Duration.ofNanos(finish - start);
    }

    private StringFileObject fromResource(String file) throws URISyntaxException, IOException {
        Path path = Paths.get(LinterTest.class.getResource(file).toURI());
        String content = new String(Files.readAllBytes(path));
        return new StringFileObject(content, path);
    }

    private static class GetCompilationUnit extends BridgeExpressionScanner {
        private CompilationUnitTree result;

        @Override
        protected void visitCompilationUnit(CompilationUnitTree node) {
            this.result = node;

            throw new AbortCompilation();
        }
    }

    private static class AbortCompilation extends RuntimeException {

    }
}

@@ -449,24 +449,54 @@
 e.Duration;%0A
+import java.util.Collections;%0A
 import java.
@@ -1261,143 +1261,116 @@
 avac
-Task task = JavacTaskBuilder.create()%0A                                         .addFile(file)%0A                                         
+Holder compiler = new JavacHolder(Collections.emptyList(), Collections.emptyList(), %22out%22);%0A        compiler
 .aft
@@ -1393,16 +1393,17 @@
 ionUnit)
+;
 %0A       
@@ -1407,62 +1407,32 @@
     
-                                 .report
+compiler.on
 Error
-s
 (errors)
 %0A   
@@ -1431,275 +1431,55 @@
 ors)
-%0A                                         .stopIfError(CompileStates.CompileState.ENTER)%0A                                         .stopIfNoError(CompileStates.CompileState.ENTER)%0A                                         .build();%0A%0A        try %7B%0A            task.call(
+;%0A        try %7B%0A            compiler.parse(file
 );%0A 

Move test to JavacHolder