package de.renew.net.inscription.transition;

import java.util.Collection;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import org.mockito.Mock;

import de.renew.engine.searcher.Occurrence;
import de.renew.engine.searcher.Searcher;
import de.renew.expression.Expression;
import de.renew.expression.VariableMapper;
import de.renew.net.NetInstance;
import de.renew.unify.Impossible;

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

/**
 * Test class for {@link DownlinkInscription}.
 * Tests only the relevant (non-trivial) methods.
 */
class DownlinkInscriptionTest extends InscriptionTest {
    private static final String INSCRIPTION_NAME = "Inscription";

    @Mock
    private Expression _mockParams;

    /**
     * Setup method to initialize this test environment.
     */
    @BeforeEach
    void setUp() throws Impossible {
        super.setUp();
    }

    /**
     * Test method for {@link DownlinkInscription#makeOccurrences(VariableMapper, NetInstance, Searcher)}.
     *
     * @param downlinkIsOptional {@code true} if the downlink is optional.
     */
    @ParameterizedTest
    @ValueSource(booleans = { true, false })
    public void testMakeOccurrences(boolean downlinkIsOptional) {
        //given
        DownlinkInscription inscription = new DownlinkInscription(
            INSCRIPTION_NAME, _mockParams, _mockExpression, downlinkIsOptional, _transition);

        //when
        Collection<Occurrence> occurrences =
            inscription.makeOccurrences(_mapper, _mockNetInstance, _searcher);

        //then
        DownlinkOccurrence expectedOccurrence = new DownlinkOccurrence(
            _mockParams, _mockExpression, INSCRIPTION_NAME, downlinkIsOptional, _mapper,
            _mockNetInstance.getInstance(_transition));

        assertThat(occurrences).isNotNull().hasSize(1);
        assertThat(occurrences).first().isInstanceOf(DownlinkOccurrence.class)
            .usingRecursiveComparison().isEqualTo(expectedOccurrence);
    }
}