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

import java.util.Arrays;
import java.util.HashMap;
import net.ranides.assira.reflection.IClass;
import net.ranides.assira.reflection.mockup.ForAnnotationUtils;
import net.ranides.assira.reflection.mockup.ForAnnotationUtils.*;
import org.junit.Test;
import static net.ranides.assira.junit.NewAssert.*;
import net.ranides.assira.text.StrBuilder;
import net.ranides.assira.text.StringUtils;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
public class AnnotationUtilsTest {

    @Test
    public void testBasic() {
        MethodInfo a1 = IClass.typeinfo(ForAnnotationUtils.class).method("m1").get().annotations().first(MethodInfo.class).get();

        MethodInfo a2 = new AnnotationBuilder<>(MethodInfo.class)
            .param("api", API.GNU)
            .param("name", "m1")
            .param("author", "ranides")
            .result();
        
        MethodInfo a4 = new AnnotationBuilder<>(MethodInfo.class).result();
        
        MethodInfo a5 = AnnotationUtils.make(MethodInfo.class);
        
//        System.out.printf("%s%n", tostr(a1));
//        System.out.printf("%s%n", tostr(a2));
//        System.out.printf("%s%n", tostr(a3));
//        System.out.printf("%s%n", tostr(a4));
        
        String exp1 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=GNU, author=ranides, name=m1, type=class java.lang.Integer, uid=77)";
        String exp2 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=null, author=null, name=null, type=class java.lang.Integer, uid=77)";
        
        assertSymEquals(exp1, tostr(a1));
        assertSymEquals(exp1, tostr(a2));
        assertSymEquals(exp2, tostr(a4));
        assertSymEquals(exp2, tostr(a5));
        
        assertSymEquals(a1, a2);
        assertSymEquals(a4, a5);
    }
    
    @Test
    public void testMutability() {
        String exp1 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=GNU, author=ranides, name=m1, type=class java.lang.Integer, uid=77)";
        String exp2 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=GNU, author=ranides, name=m4, type=class java.lang.Integer, uid=88)";

        AnnotationBuilder<MethodInfo> builder = new AnnotationBuilder<>(MethodInfo.class)
            .param("api", API.GNU)
            .param("name", "m1")
            .param("author", "ranides");
        
        MethodInfo a1 = builder.result();
        
//        System.out.printf("%s%n", tostr(a1));
        assertSymEquals(exp1, tostr(a1));
                
        builder.param("name", "m4");
        builder.param("uid", 88);
        MethodInfo a2 = builder.result();
        
//        System.out.printf("%s%n", tostr(a1));
        assertSymEquals(exp2, tostr(a1));
        assertSymEquals(exp2, tostr(a2));
        assertSymEquals(a1, a2);
        assertNotSame(a1, a2);
    }
    
    @Test
    public void testMapMutability() {
        String exp1 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=GNU, author=ranides, name=m1, type=class java.lang.Integer, uid=77)";
        String exp2 = "@net.ranides.assira.reflection.mockup.ForAnnotationUtils$MethodInfo(api=GNU, author=ranides, name=m4, type=class java.lang.Integer, uid=88)";
        HashMap<String, Object> params = new HashMap<String, Object>();

        params.put("api", API.GNU);
        params.put("name", "m1");
        params.put("author", "ranides");
        
        MethodInfo a1 = AnnotationUtils.make(MethodInfo.class, params);
        
//        System.out.printf("%s%n", tostr(a1));
        assertSymEquals(exp1, tostr(a1));
                
        params.put("name", "m4");
        params.put("uid", 88);
        MethodInfo a2 = AnnotationUtils.make(MethodInfo.class, params);
        
//        System.out.printf("%s%n", tostr(a1));
        assertSymEquals(exp2, tostr(a1));
        assertSymEquals(exp2, tostr(a2));
        assertSymEquals(a1, a2);
        assertNotSame(a1, a2);
    }
        
    
    String tostr(Object value) {
        String text = value.toString();
        String name = StringUtils.before(text, "(");
        String[] args = StringUtils.between(text, "(", ")").split(", ");
        Arrays.sort(args);
        return new StrBuilder().append(name).append("(").append(args).append(")").toString();
    }
    
}
