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

import java.text.MessageFormat;
import net.ranides.assira.reflection.IClass;
import net.ranides.assira.reflection.mockup.ForRMethod;
import static net.ranides.assira.junit.NewAssert.*;
import net.ranides.assira.text.LexicalCast;
import org.junit.Test;

/**
 *
 * @author Ranides Atterwim <ranides@gmail.com>
 */
@SuppressWarnings({"PMD.SystemPrintln", "PMD.AvoidDuplicateLiterals"})
public class RMethodTest {

    @Test
    public void testMethodReturs() {
        // @todo (assira #9) JVM BUG :)
        // ForRMethod<? super Float> p = new ForRMethod<Float>(){};
        
        // ja pierdolę. uzupełniamy TypeParams poprawnie.
        // jakkolwiek JVM trochę abstrakcyjnie te sygnatury generuje ;)

        ForRMethod p0 = new ForRMethod(){};
        ForRMethod<Float> p1 = p0;
        ForRMethod<String> p2 = p0;
        
        Object o1 = p1.new Record<Double>(){};
        Object o2 = p2.new Record<Character>(){};
        
        IClass ic1 = IClass.typefor(o1);
        IClass ic2 = IClass.typefor(o2);
        
        String o1map1 = ic1.methods().require("map1").first().toString();
        String o1map2 = ic1.methods().require("map2").first().toString();
        String o2map1 = ic2.methods().require("map1").first().toString();
        String o2map2 = ic2.methods().require("map2").first().toString();
        
        System.out.printf("1.context = %s%n", LexicalCast.toJSON(ic1.context().map()));
        System.out.printf("1.map1    = %s%n", o1map1);
        System.out.printf("1.map2    = %s%n", o1map2);
        System.out.printf("%n");
        System.out.printf("2.context = %s%n", LexicalCast.toJSON(ic2.context().map()));
        System.out.printf("2.map1    = %s%n", o2map1);
        System.out.printf("2.map2    = %s%n", o2map2);
        
        
        String e1map1 = MessageFormat.format(
            "{1}<{2}, {1}<{3}, {1}<R, {4}>>> {0}<{3}>.map1(R a, {2} b, {3} c, {4} d)",
            "net.ranides.assira.reflection.mockup.ForRMethod$Record",
            "java.util.Map",
            "java.lang.Float",
            "java.lang.Double",
            "java.lang.Integer"
        );
        String e1map2 = MessageFormat.format(
            "{1}<{2}, {1}<{3}, {1}<R, {4}>>> {0}<{3}>.map2({5}<R> a, {5}<{2}> b, {5}<{3}> c, {5}<{4}> d)", 
            "net.ranides.assira.reflection.mockup.ForRMethod$Record",
            "java.util.Map",
            "java.lang.Float",
            "java.lang.Double",
            "java.lang.Integer",
            "java.util.List"
        );
        String e2map1 = MessageFormat.format(
            "{1}<{2}, {1}<{3}, {1}<R, {4}>>> {0}<{3}>.map1(R a, {2} b, {3} c, {4} d)",
            "net.ranides.assira.reflection.mockup.ForRMethod$Record",
            "java.util.Map",
            "java.lang.String",
            "java.lang.Character",
            "java.lang.Integer"
        );
        String e2map2 = MessageFormat.format(
            "{1}<{2}, {1}<{3}, {1}<R, {4}>>> {0}<{3}>.map2({5}<R> a, {5}<{2}> b, {5}<{3}> c, {5}<{4}> d)", 
            "net.ranides.assira.reflection.mockup.ForRMethod$Record",
            "java.util.Map",
            "java.lang.String",
            "java.lang.Character",
            "java.lang.Integer",
            "java.util.List"
        );
        
        assertEquals(e1map1, o1map1);
        assertEquals(e1map2, o1map2);
        assertEquals(e2map1, o2map1);
        assertEquals(e2map2, o2map2);

        System.out.printf("%n");
    }
    
}
