package net.ranides.assira.reflection;

import net.ranides.assira.reflection.util.ReflectUtils;
import org.junit.Test;

import java.io.IOException;
import java.nio.file.Paths;
import java.util.function.Supplier;

import static org.junit.Assert.*;

@SuppressWarnings("unchecked")
public class IClassLoaderTest {

    private static final String TYPE1_CLASS = "../assira.test/target/classes/net/ranides/assira/test/Type1.class";

    @Test
    public void system() throws IOException {
        IClassLoader loader = IClassLoader.getSystem();

        Supplier<Integer> obj1 = (Supplier<Integer>)loader.defineIClass(Paths.get(TYPE1_CLASS)).construct();
        assertEquals(11, (int)obj1.get());

        Supplier<Integer> obj2 = (Supplier<Integer>)loader.defineIClass(ReflectUtils.getByteCode(SmartProducer.class)).construct();

        assertEquals(49, (int)obj2.get());
        assertFalse(obj2 instanceof SmartProducer);
    }

    @Test
    public void named() throws IOException {
        IClassLoader loader = IClassLoader.getInstance("custom", IClassLoader.getSystem());

        Supplier<Integer> obj1 = (Supplier<Integer>)loader.defineIClass(Paths.get(TYPE1_CLASS)).construct();
        assertEquals(11, (int)obj1.get());

        Supplier<Integer> obj2 = (Supplier<Integer>)loader.defineIClass(ReflectUtils.getByteCode(SmartProducer.class)).construct();

        assertEquals(49, (int)obj2.get());
        assertFalse(obj2 instanceof SmartProducer);
    }

    public static class SmartProducer implements Supplier<Integer> {

        private int v = 7;

        @Override
        public Integer get() {
            return (v = v*7);
        }

    }
}