package cz.moneta.test.harness.tests;

import cz.moneta.test.harness.HarnessJunit5Extension;
import cz.moneta.test.harness.annotations.Defect;
import cz.moneta.test.harness.annotations.Defects;
import cz.moneta.test.harness.annotations.EnableIfSet;
import cz.moneta.test.harness.annotations.EnableIfSets;
import cz.moneta.test.harness.annotations.ParameterizedTestCase;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.extensions.SystemVariableExtensionForTest;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.params.provider.ValueSource;

import static cz.moneta.test.harness.annotations.Environment.DEV;
import static cz.moneta.test.harness.annotations.Environment.EDU;
import static cz.moneta.test.harness.annotations.Environment.PPE;
import static cz.moneta.test.harness.annotations.Environment.TST1;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.junit.jupiter.api.Assertions.fail;

/**
 * These tests need config=env_test_config setting with PPE environment
 */
@ExtendWith(SystemVariableExtensionForTest.class)
@ExtendWith(HarnessJunit5Extension.class)
class HarnessJunit5ExtensionTest {

    //This test will be skipped if working correctly
    @TestCase(environments = EDU)
    void mustNotRunAsEnvironmentDoesNotMatch() {
        fail("This test should be skipped if working correctly!");
    }

    @TestCase
    void mustRunAsDefaultEnvironmentMatches() {
        assertTrue(true);
    }

    @TestCase(environments = {DEV, PPE})
    void mustRunAsOneEnvironmentMatches() {
        assertTrue(true);
    }

    @ParameterizedTestCase(environments = EDU)
    @ValueSource(strings = {"param"})
    void parametrizedMustNotRunAsEnvironmentDoesNotMatch(String param) {
        fail("This test should be skipped if working correctly!");
    }

    @ParameterizedTestCase
    @ValueSource(strings = {"param"})
    void parametrizedMustRunAsDefaultEnvironmentMatches(String param) {
        assertTrue(true);
    }

    @ParameterizedTestCase(environments = {DEV, PPE})
    @ValueSource(strings = {"param"})
    void parametrizedMustRunAsOneEnvironmentMatches(String param) {
        assertTrue(true);
    }

    @Defect("disabled in all environments by default")
    @TestCase(environments = {DEV, PPE})
    void mustNotRunAsTheTestIsDisabledAcrossAllEnvironments() {
        fail("This test should be skipped if working correctly!");
    }

    @Defect(value = "disabled only in PPE", environments = PPE)
    @TestCase(environments = PPE)
    void mustNotRunAsTheTestIsDisabledForTheSpecifiedEnvironment() {
        fail("This test should be skipped if working correctly!");
    }

    @Defect(value = "disabled in EDU", environments = EDU)
    @Defect(value = "disabled in DEV", environments = DEV)
    @Defect(value = "disabled in TST1", environments = TST1)
    @Defect(value = "disabled in PPE", environments = PPE)
    @TestCase(environments = PPE)
    void mustNotRunAsOneOfTheDefectsMatchesCurrentEnvironment() {
        fail("This test should be skipped if working correctly!");
    }

    @Defects({
            @Defect(value = "disabled in EDU", environments = EDU),
            @Defect(value = "disabled in DEV", environments = DEV),
            @Defect(value = "disabled in TST1", environments = TST1),
            @Defect(value = "disabled in PPE", environments = PPE)})
    @TestCase(environments = PPE)
    void mustNotRunAsOneOfTheDefectsMatchesCurrentEnvironmentDefectsArray() {
        fail("This test should be skipped if working correctly!");
    }

    @Defect(value = "disabled only in EDU", environments = EDU)
    @TestCase(environments = {EDU, PPE})
    void mustRunAsTheTestIsNotDisabledForCurrentEnvironment() {
        assertTrue(true);
    }

    @Disabled
    @TestCase
    void mustNotRunAsItIsDisabled() {
        fail("This test case should be skipped if working correctly!");
    }

    @TestCase
    @EnableIfSet(globalKey = "KeyA")
    void mustNotRunAsKeyAIsNotSet() {
        fail("This test case should be skipped if working correctly!");
    }

    @TestCase
    @EnableIfSets({
            @EnableIfSet(globalKey = "KeyB"),
            @EnableIfSet(globalKey = "KeyA")})
    void mustNotRunAsKeyAAndKeyBAreNotSet() {
        fail("This test case should be skipped if working correctly!");
    }

}