/*
 * Copyright 2016 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.store.service;

import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestTools;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

import static org.junit.Assert.*;

/**
 * Junit test class for TestDistributedSet.
 */
public class DistributedSetTest {

    protected InternalSetListener listener = new InternalSetListener();
    private static final String SETNAME = "set1";
    private TestDistributedSet<String> set1;
    private Set<String> set2;

    /**
     * Test setup before each test.
     */
    @Before
    public void setup() {
        set1 = new TestDistributedSet<>(SETNAME);
        set2 = new HashSet<>();

        set1.addListener(listener);
    }

    /**
     * Test cleanup after each test.
     */
    @After
    public void teardown() {
        set1.removeListener(listener);
    }

    /**
     * Basic tests against TestDistributedSet.
     */
    @Test
    public void basicTests() {
        set1.add("item1");
        assertEquals("The set name should match.", SETNAME, set1.name());
        assertEquals("The set primitive type should match.", DistributedPrimitive.Type.SET, set1.primitiveType());

        set1.add("item2");
        set1.add("item3");
        assertTrue("set1 should contain 3 items", set1.asDistributedSet().size() == 3);
        set1.remove("item1");
        set1.remove("item2");
        set1.remove("item3");
        assertTrue("set1 should be empty.", set1.asDistributedSet(0).isEmpty());
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD,
                       SetEvent.Type.REMOVE, SetEvent.Type.REMOVE, SetEvent.Type.REMOVE);
    }

    /**
     * TestDistributedSet clear method test.
     */
    @Test
    public void testClear() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        set1.clear();
        assertTrue("set1 should be empty.", set1.asDistributedSet().isEmpty());
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD,
                       SetEvent.Type.REMOVE, SetEvent.Type.REMOVE, SetEvent.Type.REMOVE);
    }

    /**
     * TestDistributedSet addAll method test.
     */
    @Test
    public void testAddAll() {
        set2.add("item1");
        set2.add("item2");
        set2.add("item3");
        set1.addAll(set2);
        assertTrue("set1 should contain 3 items.", set1.asDistributedSet().size() == set2.size());
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD);
    }

    /**
     * TestDistributedSet removeAll method test.
     */
    @Test
    public void testRemoveAll() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        set2.add("item1");
        set1.removeAll(set2);
        assertTrue("set1 should contain 2 items.", set1.asDistributedSet().size() == 2);
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD,
                       SetEvent.Type.REMOVE);
    }

    /**
     * TestDistributedSet retainAll method test.
     */
    @Test
    public void testRetainAll() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        set2.add("item4");
        set1.retainAll(set2);
        assertTrue("set1 should be empty.", set1.asDistributedSet().isEmpty());
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD,
                       SetEvent.Type.REMOVE, SetEvent.Type.REMOVE, SetEvent.Type.REMOVE);

        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        set2.add("item1");
        set1.retainAll(set2);
        assertTrue("set1 size should be 1.", set1.asDistributedSet().size() == 1);
        validateEvents(SetEvent.Type.ADD, SetEvent.Type.ADD, SetEvent.Type.ADD,
                       SetEvent.Type.REMOVE, SetEvent.Type.REMOVE);

    }

    /**
     * TestDistributedSet contains method test.
     */
    @Test
    public void testContains() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        assertTrue("set1 should contain item3.", set1.asDistributedSet().contains("item3"));
    }

    /**
     * TestDistributedSet containsAll method test.
     */
    @Test
    public void testContainsAll() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        set2.add("item2");
        set2.add("item3");
        assertTrue("set1 should contain all of set2.", set1.asDistributedSet().containsAll(set2));
    }

    /**
     * TestDistributedSet getAsImmutableSet method test.
     */
    @Test
    public void testGetAsImmutableSet() {
        set1.add("item1");
        set1.add("item2");
        set1.add("item3");
        try {
            assertEquals("set1 size should be 3.", set1.getAsImmutableSet().get().size(),
                         set1.asDistributedSet().size());
        } catch (Exception e) {
            fail("Expected exception. " + e.getMessage());
        }
    }

    /**
     * Method to validate that actual versus expected set events were
     * received correctly.
     *
     * @param types expected set events.
     */
    private void validateEvents(Enum... types) {
        TestTools.assertAfter(100, () -> {
            int i = 0;
            assertEquals("wrong events received", types.length, listener.events.size());
            for (SetEvent event : listener.events) {
                assertEquals("incorrect event type", types[i], event.type());
                i++;
            }
            listener.events.clear();
        });
    }

    /**
     * Listener class to test set events.
     */
    private class InternalSetListener implements SetEventListener<String> {
        protected List<SetEvent> events = Lists.newArrayList();

        @Override
        public void event(SetEvent event) {
            events.add(event);
        }
    }
}
