package de.accso.flexinale.common.shared_kernel;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

class ClazzHelperTest {

    interface MyInterface1 { }
    interface MyInterface2 { }

    static class MyClazzImplementingTheInterface1 implements MyInterface1 { }
    static class MyClazzImplementingTheInterface2 implements MyInterface2 { }
    static class MyClazzImplementingTheInterfaces implements MyInterface1, MyInterface2 { }
    static class MyClazzNotImplementingAnyInterface { }

    record MyRecordImplementingTheInterface1() implements MyInterface1 { }
    record MyRecordImplementingTheInterface2() implements MyInterface2 { }
    record MyRecordImplementingTheInterfaces() implements MyInterface1, MyInterface2 { }
    record MyRecordNotImplementingAnyInterface() { }

    @Test
    void testClazzImplementsInterface() {
        boolean result;

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterface1.class, MyInterface1.class);
        // assert
        assertThat(result).isTrue();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterface2.class, MyInterface2.class);
        // assert
        assertThat(result).isTrue();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterfaces.class, MyInterface1.class);
        // assert
        assertThat(result).isTrue();
        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterfaces.class, MyInterface2.class);
        // assert
        assertThat(result).isTrue();
    }

    @Test
    void testClazzNotImplementsInterface() {
        boolean result;

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterface1.class, MyInterface2.class);
        // assert
        assertThat(result).isFalse();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzImplementingTheInterface2.class, MyInterface1.class);
        // assert
        assertThat(result).isFalse();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzNotImplementingAnyInterface.class, MyInterface1.class);
        // assert
        assertThat(result).isFalse();
        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyClazzNotImplementingAnyInterface.class, MyInterface2.class);
        // assert
        assertThat(result).isFalse();
    }


    @Test
    void testRecordImplementsInterface() {
        boolean result;

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterface1.class, MyInterface1.class);
        // assert
        assertThat(result).isTrue();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterface2.class, MyInterface2.class);
        // assert
        assertThat(result).isTrue();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterfaces.class, MyInterface1.class);
        // assert
        assertThat(result).isTrue();
        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterfaces.class, MyInterface2.class);
        // assert
        assertThat(result).isTrue();
    }

    @Test
    void testRecordNotImplementsInterface() {
        boolean result;

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterface1.class, MyInterface2.class);
        // assert
        assertThat(result).isFalse();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordImplementingTheInterface2.class, MyInterface1.class);
        // assert
        assertThat(result).isFalse();

        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordNotImplementingAnyInterface.class, MyInterface1.class);
        // assert
        assertThat(result).isFalse();
        // arrange, act
        result = ClazzHelper.clazzImplementsInterface(MyRecordNotImplementingAnyInterface.class, MyInterface2.class);
        // assert
        assertThat(result).isFalse();
    }
}