package de.renew.faformalism.util;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.MockedStatic;

import de.renew.simulatorontology.shadow.SyntaxException;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mockStatic;

class FASyntaxCheckerTest {

    private final MockedStatic<SimulationSettingsManager> _simulationSettingsManagerMockedStatic =
        mockStatic(SimulationSettingsManager.class);

    private void setupAutomataModel(FAAutomatonModelEnum type) {
        _simulationSettingsManagerMockedStatic.when(SimulationSettingsManager::getAutomatonModel)
            .thenReturn(type);
    }

    @AfterEach
    public void cleanup() {
        _simulationSettingsManagerMockedStatic.close();
    }

    @ParameterizedTest
    @ValueSource(strings = { "a", "a,b,c", "a,  b,   c, d  ", "" })
    public void testCheckValidArcSyntaxForNFAs(String inscription) {
        //given
        setupAutomataModel(FAAutomatonModelEnum.NFA);
        //when/then
        assertDoesNotThrow(() -> FASyntaxChecker.checkArcSyntax(inscription));
    }

    @ParameterizedTest
    @ValueSource(strings = { "aa", "a.b", "_:'2", "00", "0;a", "a, b->s" })
    public void testCheckInvalidArcSyntaxForNFAs(String inscription) {
        //given
        setupAutomataModel(FAAutomatonModelEnum.NFA);
        //when/then
        assertThrows(SyntaxException.class, () -> FASyntaxChecker.checkArcSyntax(inscription));
    }

    @ParameterizedTest
    @ValueSource(
        strings = { "a,a->b", "0, $->$", " t, ->", "x,y->z\na,b->c", ",a->b", ",->", "a,->d" })
    public void testCheckValidArcSyntaxForPDAs(String inscription) {
        //given
        setupAutomataModel(FAAutomatonModelEnum.PDA);
        //when/then
        assertDoesNotThrow(() -> FASyntaxChecker.checkArcSyntax(inscription));
    }

    @ParameterizedTest
    @ValueSource(strings = { "a,a->sb", "0,a", " t", "a; a->b", "" })
    public void testCheckInvalidArcSyntaxForPDAs(String inscription) {
        //given
        setupAutomataModel(FAAutomatonModelEnum.PDA);
        //when/then
        assertThrows(SyntaxException.class, () -> FASyntaxChecker.checkArcSyntax(inscription));
    }
}