/*
 * Copyright 2018-present Open Networking Foundation
 *
 * 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.openstacknetworking.impl;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_UPDATE;

/**
 * Unit tests for pre-commit port manager.
 */
public class PreCommitPortManagerTest {

    private static final String PORT_ID_1 = "port-1";
    private static final String PORT_ID_2 = "port-2";

    private static final String CLASS_NAME_1 = "class-1";
    private static final String CLASS_NAME_2 = "class-2";

    private PreCommitPortManager target;

    /**
     * Initializes this unit test.
     */
    @Before
    public void setUp() {
        target = new PreCommitPortManager();
        target.activate();
    }

    /**
     * Tears down this unit test.
     */
    @After
    public void tearDown() {
        target.deactivate();
    }

    /**
     * Tests subscribe pre-commit method.
     */
    @Test
    public void testSubscribePreCommit() {

        sampleSubscribe();

        assertEquals(1, target.subscriberCountByEventType(PORT_ID_1, OPENSTACK_PORT_PRE_REMOVE));
        assertEquals(2, target.subscriberCountByEventType(PORT_ID_2, OPENSTACK_PORT_PRE_REMOVE));

        assertEquals(0, target.subscriberCountByEventType(PORT_ID_1, OPENSTACK_PORT_PRE_UPDATE));
        assertEquals(1, target.subscriberCountByEventType(PORT_ID_2, OPENSTACK_PORT_PRE_UPDATE));

        assertEquals(1, target.subscriberCount(PORT_ID_1));
        assertEquals(3, target.subscriberCount(PORT_ID_2));
    }

    /**
     * Tests unsubscribe pre-commit method.
     */
    @Test
    public void testUnsubscribePreCommit() {

        sampleSubscribe();

        target.unsubscribePreCommit(PORT_ID_1, OPENSTACK_PORT_PRE_REMOVE, CLASS_NAME_1);
        target.unsubscribePreCommit(PORT_ID_2, OPENSTACK_PORT_PRE_REMOVE, CLASS_NAME_2);

        assertEquals(0, target.subscriberCountByEventType(PORT_ID_1, OPENSTACK_PORT_PRE_REMOVE));
        assertEquals(1, target.subscriberCountByEventType(PORT_ID_2, OPENSTACK_PORT_PRE_REMOVE));

        assertEquals(0, target.subscriberCount(PORT_ID_1));
        assertEquals(2, target.subscriberCount(PORT_ID_2));
    }

    private void sampleSubscribe() {

        target.subscribePreCommit(PORT_ID_1, OPENSTACK_PORT_PRE_REMOVE, CLASS_NAME_1);

        target.subscribePreCommit(PORT_ID_2, OPENSTACK_PORT_PRE_REMOVE, CLASS_NAME_1);
        target.subscribePreCommit(PORT_ID_2, OPENSTACK_PORT_PRE_REMOVE, CLASS_NAME_2);

        target.subscribePreCommit(PORT_ID_2, OPENSTACK_PORT_PRE_UPDATE, CLASS_NAME_1);
    }
}
