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

import java.io.IOException;
import java.util.Locale;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileObject;
import javax.tools.StandardLocation;
import net.ranides.assira.annotations.javac.JavaCompilation;
import net.ranides.assira.annotations.javac.JavaCompilationResult;
import net.ranides.assira.text.IOStrings;
import net.ranides.assira.text.StringUtils;
import static org.junit.Assert.*;
import org.junit.Test;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class JavaServiceProcessorTest {
    
    private static final String FILE_SRC_1 = 
        "package net.ranides.at; \n"+
        "@net.ranides.assira.annotations.Meta.JavaService \n" +
        "public class HelloWorld implements net.ranides.assira.events.Event { }";
    
    private static final String FILE_SRC_1E = 
        "package net.ranides.at; \n"+
        "@net.ranides.assira.annotations.Meta.JavaService \n" +
        "public class HelloWorld { }";
    
    private static final String FILE_SRC_2 = 
        "package net.ranides.at; \n"+
        "@net.ranides.assira.annotations.Meta.JavaService(net.ranides.assira.events.Event.class) \n" +
        "public class ImpS2 implements net.ranides.assira.events.Event { }";
    
    private static final String FILE_SRC_3 = 
        "package net.ranides.at; \n"+
        "import java.nio.charset.Charset; \n" +
        "import java.util.Iterator; \n" +
        " \n" +
        "@net.ranides.assira.annotations.Meta.JavaService \n" +
        "public class CPService extends java.nio.charset.spi.CharsetProvider { \n" +
            "public Iterator<Charset> charsets() { return null; } \n" +
            "public Charset charsetForName(String charsetName) { return null; } \n" + 
        "}";

    @Test
    public void testJSP1() throws IOException {
        JavaCompilationResult re = 
            new JavaCompilation()
            .processor(new JavaServiceProcessor())
            .source("net.ranides.at.HelloWorld", FILE_SRC_1)
            .compile();

        assertTrue(re.success());
        
        JavaFileObject file1 = re.file(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/net.ranides.assira.events.Event");
        assertEquals(String.format("net.ranides.at.HelloWorld%n"), IOStrings.read(file1.openReader(false)));
    }
    
    @Test
    public void testJSP2() throws IOException {
        JavaCompilationResult re = 
            new JavaCompilation()
            .processor(new JavaServiceProcessor())
            .source("net.ranides.at.HelloWorld", FILE_SRC_1)
            .source("net.ranides.at.ImpS2", FILE_SRC_2)
            .source("net.ranides.at.CPService", FILE_SRC_3)
            .compile();

        for(Diagnostic<? extends JavaFileObject> d : re.diagnostics()) {
            System.out.printf("%s%n", d);
        }

        assertTrue(re.success());
        
        JavaFileObject file1 = re.file(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/net.ranides.assira.events.Event");
        assertEquals(String.format("net.ranides.at.HelloWorld%nnet.ranides.at.ImpS2%n"), IOStrings.read(file1.openReader(false)));
        
        JavaFileObject file2 = re.file(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/java.nio.charset.spi.CharsetProvider");
        assertEquals(String.format("net.ranides.at.CPService%n"), IOStrings.read(file2.openReader(false)));
    }
    
    @Test
    public void testJSP3() throws IOException {

        JavaCompilationResult re = 
            new JavaCompilation()
            .processor(new JavaServiceProcessor())
            .source("net.ranides.at.HelloWorld", FILE_SRC_1)
            .source("net.ranides.at.ImpS2", FILE_SRC_2)
            .source("net.ranides.at.CPService", FILE_SRC_3)
            .resource("META-INF/services/java.nio.charset.spi.CharsetProvider")
            .compile();

        for(Diagnostic<? extends JavaFileObject> d : re.diagnostics()) {
            System.out.printf("%s%n", d);
        }

        assertTrue(re.success());
        
        JavaFileObject file1 = re.file(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/net.ranides.assira.events.Event");
        assertEquals(String.format("net.ranides.at.HelloWorld%nnet.ranides.at.ImpS2%n"), IOStrings.read(file1.openReader(false)));
        
        JavaFileObject file2 = re.file(StandardLocation.CLASS_OUTPUT, "", "META-INF/services/java.nio.charset.spi.CharsetProvider");
        assertEquals(String.format("net.ranides.at.CPService%nnet.ranides.assira.text.MazoviaCharset%n"), IOStrings.read(file2.openReader(false)));
    }
    
    @Test
    public void testJSP1_Error() throws IOException {

        JavaCompilationResult re = 
            new JavaCompilation()
            .processor(new JavaServiceProcessor())
            .source("net.ranides.at.HelloWorld", FILE_SRC_1E)
            .compile();

        assertFalse(re.success());
        
        String error = re.diagnostics().stream()
            .filter(d -> Kind.ERROR==d.getKind())
            .findFirst()
            .get()
            .getMessage(Locale.ROOT);
        
        assertEquals("Contract type was not specified, but it couldn't be inferred.", error);
    }
    
}
