/*
 * Copyright 2016-present 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.net.region.impl;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.junit.TestUtils;
import org.onlab.util.ItemNotFoundException;
import org.onosproject.cluster.NodeId;
import org.onosproject.common.event.impl.TestEventDispatcher;
import org.onosproject.net.DeviceId;
import org.onosproject.net.NetTestTools;
import org.onosproject.net.region.Region;
import org.onosproject.net.region.RegionAdminService;
import org.onosproject.net.region.RegionEvent;
import org.onosproject.net.region.RegionId;
import org.onosproject.net.region.RegionListener;
import org.onosproject.store.region.impl.DistributedRegionStore;
import org.onosproject.store.service.TestStorageService;

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

import static org.junit.Assert.*;
import static org.onosproject.net.region.Region.Type.*;
import static org.onosproject.net.region.RegionEvent.Type.*;

/**
 * Tests of the region service implementation.
 */
public class RegionManagerTest {

    private static final RegionId RID1 = RegionId.regionId("r1");
    private static final RegionId RID2 = RegionId.regionId("r2");

    private static final DeviceId DID1 = DeviceId.deviceId("foo:d1");
    private static final DeviceId DID2 = DeviceId.deviceId("foo:d2");
    private static final DeviceId DID3 = DeviceId.deviceId("foo:d3");

    private static final NodeId NID1 = NodeId.nodeId("n1");

    private static final List<Set<NodeId>> MASTERS = ImmutableList.of(ImmutableSet.of(NID1));

    private TestManager manager = new TestManager();
    private RegionAdminService service;
    private TestStore store = new TestStore();
    private TestListener listener = new TestListener();

    @Before
    public void setUp() throws Exception {
        TestUtils.setField(store, "storageService", new TestStorageService());
        store.activate();

        manager.store = store;
        manager.addListener(listener);
        NetTestTools.injectEventDispatcher(manager, new TestEventDispatcher());
        manager.activate();
        service = manager;
    }

    @After
    public void tearDown() {
        store.deactivate();
        manager.removeListener(listener);
        manager.deactivate();
        NetTestTools.injectEventDispatcher(manager, null);
    }

    @Test
    public void basics() {
        Region r1 = service.createRegion(RID1, "R1", METRO, MASTERS);
        assertEquals("incorrect id", RID1, r1.id());
        assertEquals("incorrect event", REGION_ADDED, listener.event.type());

        Region r2 = service.createRegion(RID2, "R2", CAMPUS, MASTERS);
        assertEquals("incorrect id", RID2, r2.id());
        assertEquals("incorrect type", CAMPUS, r2.type());
        assertEquals("incorrect event", REGION_ADDED, listener.event.type());

        r2 = service.updateRegion(RID2, "R2", COUNTRY, MASTERS);
        assertEquals("incorrect type", COUNTRY, r2.type());
        assertEquals("incorrect event", REGION_UPDATED, listener.event.type());

        Set<Region> regions = service.getRegions();
        assertEquals("incorrect size", 2, regions.size());
        assertTrue("missing r1", regions.contains(r1));
        assertTrue("missing r2", regions.contains(r2));

        r1 = service.getRegion(RID1);
        assertEquals("incorrect id", RID1, r1.id());

        service.removeRegion(RID1);
        regions = service.getRegions();
        assertEquals("incorrect size", 1, regions.size());
        assertTrue("missing r2", regions.contains(r2));
        assertEquals("incorrect event", REGION_REMOVED, listener.event.type());
    }

    @Test(expected = IllegalArgumentException.class)
    public void duplicateCreate() {
        service.createRegion(RID1, "R1", METRO, MASTERS);
        service.createRegion(RID1, "R2", CAMPUS, MASTERS);
    }

    @Test(expected = ItemNotFoundException.class)
    public void missingUpdate() {
        service.updateRegion(RID1, "R1", METRO, MASTERS);
    }

    @Test
    public void membership() {
        Region r = service.createRegion(RID1, "R1", METRO, MASTERS);
        assertTrue("no devices expected", service.getRegionDevices(RID1).isEmpty());
        assertNull("no region expected", service.getRegionForDevice(DID1));

        service.addDevices(RID1, ImmutableSet.of(DID1, DID2));
        Set<DeviceId> deviceIds = service.getRegionDevices(RID1);
        assertEquals("incorrect device count", 2, deviceIds.size());
        assertTrue("missing d1", deviceIds.contains(DID1));
        assertTrue("missing d2", deviceIds.contains(DID2));
        assertEquals("wrong region", r, service.getRegionForDevice(DID1));
        assertEquals("incorrect event", REGION_MEMBERSHIP_CHANGED, listener.event.type());

        service.addDevices(RID1, ImmutableSet.of(DID3));
        deviceIds = service.getRegionDevices(RID1);
        assertEquals("incorrect device count", 3, deviceIds.size());
        assertTrue("missing d3", deviceIds.contains(DID3));
        assertEquals("incorrect event", REGION_MEMBERSHIP_CHANGED, listener.event.type());

        service.addDevices(RID1, ImmutableSet.of(DID3, DID1));
        deviceIds = service.getRegionDevices(RID1);
        assertEquals("incorrect device count", 3, deviceIds.size());

        service.removeDevices(RID1, ImmutableSet.of(DID2, DID3));
        deviceIds = service.getRegionDevices(RID1);
        assertEquals("incorrect device count", 1, deviceIds.size());
        assertTrue("missing d1", deviceIds.contains(DID1));

        service.removeDevices(RID1, ImmutableSet.of(DID1, DID3));
        assertTrue("no devices expected", service.getRegionDevices(RID1).isEmpty());

        service.removeDevices(RID1, ImmutableSet.of(DID2));
        assertTrue("no devices expected", service.getRegionDevices(RID1).isEmpty());
    }

    private class TestStore extends DistributedRegionStore {
        @Override
        protected void activate() {
            super.activate();
        }

        @Override
        protected void deactivate() {
            super.deactivate();
        }
    }

    private class TestManager extends RegionManager {
        TestManager() {
            eventDispatcher = new TestEventDispatcher();
        }
    }

    private class TestListener implements RegionListener {
        RegionEvent event;

        @Override
        public void event(RegionEvent event) {
            this.event = event;
        }
    }
}