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

import java.util.ArrayList;
import java.util.List;
import javax.tools.Diagnostic;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;

/**
 * This class represents result of javac compilation session.
 *
 * It can't be created directly. Please use {@link JavaCompilation}.
 *
 * @author Ranides Atterwim {@literal <ranides@gmail.com>}
 */
public class JavaCompilationResult {
    
    private final boolean success;
    
    private final List<Diagnostic<? extends JavaFileObject>> diagnostics;
    
    private final List<JavaFileObject> files;

    JavaCompilationResult(
        boolean successful, 
        List<Diagnostic<? extends JavaFileObject>> diagnostics,
        List<JavaFileObject> generatedFiles
    ) {
        this.success = successful && diagnostics.stream().noneMatch(d -> d.getKind() == Diagnostic.Kind.ERROR);
        this.diagnostics = new ArrayList<>(diagnostics);
        this.files = new ArrayList<>(generatedFiles);
    }

    /**
     * Returns true if compilation finished without errors.
     *
     * @return boolean
     */
    public boolean success() {
        return success;
    }

    /**
     * Returns list of all diagnostic messages, including errors.
     *
     * @return list
     */
    public List<Diagnostic<? extends JavaFileObject>> diagnostics() {
        return diagnostics;
    }

    /**
     * Returns list of all generated files, including resource files.
     *
     * @return list
     */
    public List<JavaFileObject> files() {
        return files;
    }


    /**
     * Returns generated file inside standard StandardLocation.CLASS_OUTPUT
     * This version is preferred when loading resource files.
     *
     * @param packageName packageName
     * @param relativeName relativeName
     * @return JavaFileObject
     */
    public JavaFileObject file(String packageName, String relativeName) {
        return file(JavaCompilationFM.getName(StandardLocation.CLASS_OUTPUT, packageName, relativeName));
    }

    /**
     * Returns generated file inside standard StandardLocation.CLASS_OUTPUT
     * This version is preferred when loading class files.
     *
     * @param className className
     * @param kind kind
     * @return JavaFileObject
     */
    public JavaFileObject file(String className, JavaFileObject.Kind kind) {
        return file(JavaCompilationFM.getName(StandardLocation.CLASS_OUTPUT, className, kind));
    }

    private JavaFileObject file(String name) {
        return files.stream().filter(o -> name.equals(o.getName())).findFirst().orElse(null);
    }
    
}
