/*
 * @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.io.IOException;
import java.lang.reflect.Field;
import java.nio.file.Files;
import java.nio.file.Path;
import net.ranides.assira.reflection.mockup.ForMemberTraits;
import static net.ranides.assira.junit.NewAssert.*;
import net.ranides.assira.text.StringUtils;
import org.junit.Test;

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

    @Test
    public void testAccess() throws IllegalArgumentException, IllegalAccessException {
        Field a = ReflectUtils.access(ForMemberTraits.$field("f_public"));
        Field b = ReflectUtils.access(ForMemberTraits.$field("f_private"));
        Field c = ReflectUtils.access(b);
        
        ForMemberTraits object = new ForMemberTraits(){
            @Override
            public void m_abstract() {
                throw new UnsupportedOperationException();
            }
        };
        
        assertEquals(77, a.get(object));
        assertEquals(99, b.get(object));
        assertEquals(99, c.get(object));
    }
    
    @Test
    public void testSource() throws IOException {
        String re = StringUtils.escapeRE("String src2 = ReflectUtils.getSource(ReflectUtilsTest.class);");
        
        String src1 = ReflectUtils.getSource("net.ranides.assira.reflection.util.ReflectUtilsTest");
        String src2 = ReflectUtils.getSource(ReflectUtilsTest.class);
        
        assertEquals(src1, src2);
        assertEquals(3, src1.split(re).length);
        
        String src3 = ReflectUtils.getSource("net.ranides.assira.reflection.util.ReflectUtils");
        String src4 = ReflectUtils.getSource(ReflectUtils.class);
        
        assertEquals(src3, src4);
        assertTrue(src3.contains("return readSourceCode(ClassUtils.loader(), classname);"));
        
        assertThrows(IOException.class, ()->{
            ReflectUtils.getSource("net.ranides.InvalidClass");
        });
    }
    
    @Test
    public void testLocation() {
        Path p1 = ReflectUtils.getLocation(ReflectUtils.class);
        assertTrue(p1.endsWith("assira/assira/target/classes"));
        assertTrue(Files.exists(p1));
        
        Path p2 = ReflectUtils.getLocation(ReflectUtilsTest.class);
        assertTrue(p2.endsWith("assira/assira/target/test-classes"));
        assertTrue(Files.exists(p2));
        
        assertThrows(RuntimeException.class, ()->{
            ReflectUtils.getLocation(String.class);
        });
    }
    
    @Test
    public void testFQLocation() {
        System.out.printf("%s%n", ReflectUtils.getFQLocation(ReflectUtils.class));
        System.out.printf("%s%n", ReflectUtils.getFQLocation(ReflectUtilsTest.class));
        Path p1 = ReflectUtils.getFQLocation(ReflectUtils.class);
        
        assertTrue(p1.endsWith("assira/assira/target/classes/net/ranides/assira/reflection/util/ReflectUtils.class"));
        assertTrue(Files.exists(p1));
  
        Path p2 = ReflectUtils.getFQLocation(ReflectUtilsTest.class);
        assertTrue(p2.endsWith("assira/assira/target/test-classes/net/ranides/assira/reflection/util/ReflectUtilsTest.class"));
        assertTrue(Files.exists(p2));

        assertThrows(RuntimeException.class, ()->{
            ReflectUtils.getFQLocation(String.class);
        });
    }
    
    
}
