/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.annotations.javac;


import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.annotation.processing.Processor;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileObject;
import javax.tools.ToolProvider;
import net.ranides.assira.text.Charsets;

public final class JavaCompilation {

    private final List<String> options;

    private final List<Processor> processors = new ArrayList<>();
    
    private final List<JavaFileObject> sources = new ArrayList<>();
    
    private final List<String> resources = new ArrayList<>();

    public JavaCompilation(String... options) {
        this.options = Arrays.asList(options);
    }
    
    public JavaCompilation processor(Processor processor) {
        processors.add(processor);
        return this;
    }
    
    public JavaCompilation source(String fqname, String source) {
        sources.add(new JavaCompilationFM.CFOString(fqname, source));
        return this;
    }
    
    public JavaCompilation source(URL resource) {
        sources.add(new JavaCompilationFM.CFOResource(resource));
        return this;
    }
    
    public JavaCompilation resource(String resource) {
        resources.add(resource);
        return this;
    }

    public JavaCompilationResult compile() throws IOException {
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
        if (compiler == null) {
            throw new IllegalStateException("Java Compiler is not present. May be, you need to include tools.jar on your dependency list.");
        }
        DiagnosticCollector<JavaFileObject> dc = new DiagnosticCollector<>();

        JavaCompilationFM fm = new JavaCompilationFM(compiler.getStandardFileManager(dc, Locale.getDefault(), Charsets.UTF8));
        
        for(String rs : resources) {
            fm.exportResource(rs);
        }

        CompilationTask task = compiler.getTask(
            null, // explicitly use the default because old versions of javac log some output on stderr
            fm,
            dc,
            options,
            Collections.emptyList(),
            sources
        );
        task.setProcessors(processors);
        boolean successful = task.call();
        return new JavaCompilationResult(successful, dc.getDiagnostics(), fm.getOutputFiles());
    }

}
