package architecturetests;

import com.tngtech.archunit.lang.ArchRule;
import com.tngtech.archunit.lang.EvaluationResult;
import com.tngtech.archunit.lang.syntax.ArchRuleDefinition;
import de.accso.flexinale.common.shared_kernel.DoNotCheckInArchitectureTests;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.util.stream.Stream;

import static architecturetests.FlexinaleComponent.*;
import static org.assertj.core.api.Assertions.assertThat;

public class NoDependenciesToSpringTest {

    private static Stream<Arguments> allFlexinaleComponents() {
        return Stream.of(
                  Arguments.of(besucherportal.name)
                , Arguments.of(common.name)
                , Arguments.of(security.name)
                , Arguments.of(security_api_contract.name)
                , Arguments.of(backoffice.name)
                , Arguments.of(backoffice_api_contract.name)
                , Arguments.of(ticketing.name)
                , Arguments.of(ticketing_api_contract.name)
        );
    }

    @ParameterizedTest
    @MethodSource("allFlexinaleComponents")
    void test_NoDependenciesToSpringInCore(final String component) {
        // arrange
        final String componentPackagePrefix = ArchUnitHelper.PACKAGE_PREFIX + "." + component;
        final String applicationPackage = componentPackagePrefix + ".application..";
        final String      domainPackage = componentPackagePrefix + ".domain..";

        ArchRule archRule = ArchRuleDefinition.noClasses()
                .that()
                .areNotAnnotatedWith(DoNotCheckInArchitectureTests.class)
                .and()
                .resideInAnyPackage(applicationPackage, domainPackage)
                .should()
                .beAnnotatedWith(ArchUnitHelper.isSpringAnnotation)
                .orShould()
                .dependOnClassesThat(ArchUnitHelper.isSpringClass);

        // act
        EvaluationResult evaluationResult = archRule.evaluate(ArchUnitHelper.allJavaClassesToCheck);

        // assert
        assertThat(evaluationResult.getFailureReport().getDetails()).isEmpty();
    }

    @Test
    void test_NoDependenciesToSpringInSharedKernel() {
        // arrange
        final String PACKAGE_SHARED_KERNEL = ArchUnitHelper.PACKAGE_PREFIX + ".common.shared_kernel..";

        ArchRule archRule = ArchRuleDefinition.noClasses()
                .that()
                .resideInAnyPackage(PACKAGE_SHARED_KERNEL)
                .should()
                .beAnnotatedWith(ArchUnitHelper.isSpringAnnotation)
                .orShould()
                .dependOnClassesThat(ArchUnitHelper.isSpringClass);

        // act
        EvaluationResult evaluationResult = archRule.evaluate(ArchUnitHelper.allJavaClassesToCheck);

        // assert
        assertThat(evaluationResult.getFailureReport().getDetails()).isEmpty();
    }
}
