package cz.moneta.test.harness.tests.context;

import cz.moneta.test.harness.BaseHarness;
import cz.moneta.test.harness.annotations.TestCase;
import cz.moneta.test.harness.annotations.TestScenario;
import cz.moneta.test.harness.exception.HarnessException;
import cz.moneta.test.harness.extensions.SystemVariableExtensionForTest;
import cz.moneta.test.harness.tests.UnitTestEndpoint;
import org.junit.Assert;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.ExtendWith;

import static cz.moneta.test.harness.support.data.GeneratorType.RC;

/**
 * These tests need config=env_test_config setting with PPE environment
 */
@ExtendWith(SystemVariableExtensionForTest.class)
@TestScenario(name = "BaseStoreAccessor unit tests")
public class BaseStoreAccessorTest {

    private static final String TEST_VALUE = "TEST_VALUE";
    private static final String TEST_KEY = "TEST_KEY";
    private static final String TEST_KEY_GLOBAL = "TEST_KEY_GLOBAL";
    private static final Object TEST_OBJECT = new Object();

    @TestCase(name = "Test harness store functionality store and get with existing key")
    void storeValuesStringPositiveTest(BaseHarness harness) {
        harness.store(TEST_KEY, TEST_VALUE);
        Assert.assertEquals(harness.get(TEST_KEY), TEST_VALUE);
    }

    @TestCase(name = "Test harness store functionality store and get with existing key")
    void storeValuesObjectPositiveTest(BaseHarness harness) {
        harness.store(TEST_KEY, TEST_OBJECT);
        Assert.assertSame(harness.get(TEST_KEY), TEST_OBJECT);
    }

    @TestCase(name = "Test harness store functionality store and get without existing key")
    void storeValuesNegativeTest(BaseHarness harness) {
        Assertions.assertThrows(HarnessException.class, () -> harness.get(TEST_KEY));
    }

    @TestCase(name = "Test harness global store functionality store and get with existing key")
    void globalStoreValuesObjectPositiveTest(BaseHarness harness) {
        harness.storeGlobal(TEST_KEY_GLOBAL, TEST_OBJECT);
        Assert.assertSame(harness.getGlobal(TEST_KEY_GLOBAL), TEST_OBJECT);
    }

    @TestCase(name = "Test harness global store functionality store and get with existing key")
    void globalStoreValuesStringPositiveTest(BaseHarness harness) {
        harness.storeGlobal(TEST_KEY_GLOBAL, TEST_VALUE);
        Assert.assertSame(harness.getGlobal(TEST_KEY_GLOBAL), TEST_VALUE);
    }

    @TestCase(name = "Test to using general generator")
    void testGeneratePositive(BaseHarness harness) {
        Assert.assertSame("1234", harness.generate(RC));
    }

    @TestCase(name = "Test harness init endpoint and check")
    void getEndpointPositiveTest(BaseHarness harness) {
        harness.getEndpoint(UnitTestEndpoint.class);
        Object initEndpoint = harness.getActiveEndpoints()
                .stream()
                .findAny()
                .get()
                .getClass();
        Assert.assertSame(UnitTestEndpoint.class, initEndpoint);
    }

    @TestCase(name = "Test harness init and close endpoint")
    void closeEndpointPositiveTest(BaseHarness harness) {
        UnitTestEndpoint activeUnitTestEndpoint = harness.getEndpoint(UnitTestEndpoint.class);
        harness.closeEndpoint(activeUnitTestEndpoint);
        boolean initEndpoint = harness.getActiveEndpoints()
                .stream()
                .findAny()
                .isPresent();
        Assert.assertTrue(!initEndpoint);
    }
}