package targetast;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class GreaterEqualTest {
    static Class<?> classToTest;
    static Object instance;

    @BeforeAll
    public static void beforeClass() throws Exception {
        var classFiles = TestCodegen.generateClassFiles(TestCodegen.createClassLoader(), "GreaterEqual.jav");
        classToTest = classFiles.get("GreaterEqual");
        instance = classToTest.getDeclaredConstructor().newInstance();
    }

    @Test
    public void testIntegers() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 7, 5);
        assertTrue(result);
    }

    @Test
    public void testIntegers2() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5, 7);
        assertFalse(result);
    }

    @Test
    public void testEqIntegers() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Integer.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5, 5);
        assertTrue(result);
    }

    @Test
    public void testLongs() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Method gE = classToTest.getDeclaredMethod("gE", Long.class, Long.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 10L, 7L);
        assertTrue(result);
    }

    @Test
    public void testFloats() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Float.class, Float.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5F, 7F);
        assertFalse(result);
    }

    @Test
    public void testDoubles() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Double.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5.0, 7.0);
        assertFalse(result);
    }

    @Test
    public void testLongInt() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Long.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 15L, 7);
        assertTrue(result);
    }

    @Test
    public void testFloatInt() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Float.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5F, 7);
        assertFalse(result);
    }

    @Test
    public void testDoubleInt() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Integer.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 25.0, 17);
        assertTrue(result);
    }

    @Test
    public void testFloatLong() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Float.class, Long.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 75F, 70L);
        assertTrue(result);
    }

    @Test
    public void testDoubleLong() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Long.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 5.0, 7L);
        assertFalse(result);
    }

    @Test
    public void testEqDoubleFloat() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 7.0, 7F);
        assertTrue(result);
    }

    @Test
    public void testDoubleFloat() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 15.0, 7F);
        assertTrue(result);
    }

    @Test
    public void testDoubleFloat3() throws Exception {
        Method gE = classToTest.getDeclaredMethod("gE", Double.class, Float.class);
        gE.setAccessible(true);
        Boolean result = (Boolean) gE.invoke(instance, 9.0, 17F);
        assertFalse(result);
    }
}
