package net.onrc.onos.core.matchaction;

import org.junit.Test;

import java.util.ArrayList;
import java.util.Set;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

/**
 * Unit tests for the MatchActionModule.
 */
public class MatchActionModuleTest {

    /**
     * Tests that MatchAction objects added by the executeOperations()
     * method are properly returned by the getMatchActions() method.
     */
    @Test
    public void testMatchActionModuleGlobalEntriesSet() {

        final int iterations = 5;
        final MatchActionModule module = new MatchActionModule();
        final ArrayList<MatchAction> generatedMatchActions = new ArrayList<>();

        // Add some test MatchAction objects. 25 will be added, in 5 blocks
        // of 5.
        for (int operationsIteration = 1;
             operationsIteration <= iterations;
             operationsIteration++) {
            final MatchActionOperationsId id =
                    MatchActionOperationsId.createNewOperationsId();
            assertThat(id, is(notNullValue()));
            final MatchActionOperations operations =
                    MatchActionOperations.createMatchActionsOperations(id);
            assertThat(operations, is(notNullValue()));

            for (int entriesIteration = 1;
                 entriesIteration <= iterations;
                 entriesIteration++) {

                final String entryId = "MA" +
                        Integer.toString(operationsIteration) +
                        Integer.toString(entriesIteration);
                final MatchAction matchAction =
                        new MatchAction(entryId, null, null, null);
                final MatchActionOperationEntry entry =
                        new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
                                                      matchAction);
                operations.addOperation(entry);
                generatedMatchActions.add(matchAction);
            }

            // Add the MatchActions generated by this iteration
            final boolean result = module.executeOperations(operations);
            assertThat(result, is(true));
        }

        // Get the list of generated MatchAction objects and make sure its
        // length is correct.
        final int generatedCount = generatedMatchActions.size();
        final Set<MatchAction> matchActions = module.getMatchActions();
        assertThat(matchActions, hasSize(generatedCount));

        // Make sure that all the created items are in the list
        final MatchAction[] generatedArray =
                generatedMatchActions.toArray(new MatchAction[generatedCount]);
        assertThat(matchActions, containsInAnyOrder(generatedArray));

        //  Make sure that the returned list cannot be modified
        Throwable errorThrown = null;
        try {
            matchActions.add(new MatchAction("", null, null, null));
        } catch (UnsupportedOperationException e) {
            errorThrown = e;
        }
        assertThat(errorThrown, is(notNullValue()));
    }

    /**
     * Tests that adding a duplicate MatchAction via executeOperations()
     * returns an error.
     */
    @Test
    public void testAddingDuplicateMatchAction() {

        // Create two MatchAction objects using the same ID
        final MatchAction matchAction =
                new MatchAction("ID", null, null, null);
        final MatchAction duplicateMatchAction =
                new MatchAction("ID", null, null, null);

        // create Operation Entries for the two MatchAction objects
        final MatchActionOperationEntry entry =
                new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
                        matchAction);
        final MatchActionOperationEntry duplicateEntry =
                new MatchActionOperationEntry(MatchActionOperations.Operator.ADD,
                        duplicateMatchAction);

        // Create an Operations object to execute the first MatchAction
        final MatchActionOperationsId id =
                MatchActionOperationsId.createNewOperationsId();
        assertThat(id, is(notNullValue()));
        final MatchActionOperations operations =
                MatchActionOperations.createMatchActionsOperations(id);
        operations.addOperation(entry);

        // Create a module to use to execute the Operations.
        final MatchActionModule module = new MatchActionModule();

        // Execute the first set of Operations.  This
        // should succeed.
        final boolean result = module.executeOperations(operations);
        assertThat(result, is(true));

        // Now add the duplicate entry.  This should fail.
        final MatchActionOperationsId idForDuplicate =
                MatchActionOperationsId.createNewOperationsId();
        assertThat(idForDuplicate, is(notNullValue()));
        final MatchActionOperations operationsForDuplicate =
                MatchActionOperations.createMatchActionsOperations(idForDuplicate);
        operationsForDuplicate.addOperation(duplicateEntry);

        final boolean resultForDuplicate =
                module.executeOperations(operationsForDuplicate);
        assertThat(resultForDuplicate, is(false));

        // Now add the original entry again.  This should fail.
        final boolean resultForAddAgain = module.executeOperations(operations);
        assertThat(resultForAddAgain, is(false));
    }
}
