/*
 * Copyright 2017-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.mapping;

import com.google.common.testing.EqualsTester;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.event.AbstractEventTest;
import org.onosproject.net.DeviceId;

import java.util.concurrent.TimeUnit;

/**
 * Unit tests for the MappingEvent class.
 */
public class MappingEventTest extends AbstractEventTest {

    private MappingEvent event1;
    private MappingEvent sameAsEvent1;
    private MappingEvent event2;

    /**
     * Creates a mock of mapping object from mappingId and deviceId.
     *
     * @param mid mapping identifier
     * @param did device identifier
     * @return mock of mapping object
     */
    private Mapping mockMapping(long mid, String did) {
        Mapping.Builder builder = new DefaultMapping.Builder();
        DeviceId deviceId = DeviceId.deviceId(did);

        return builder
                .withId(mid)
                .withKey(new DefaultMappingKey())
                .withValue(new DefaultMappingValue())
                .forDevice(deviceId)
                .build();
    }

    @Before
    public void setup() {
        final Mapping mapping1 = mockMapping(1, "lisp:10.1.1.1");
        final Mapping mapping2 = mockMapping(2, "lisp:10.1.1.2");

        event1 = new MappingEvent(MappingEvent.Type.MAPPING_ADDED, mapping1);
        sameAsEvent1 = new MappingEvent(MappingEvent.Type.MAPPING_ADDED, mapping1);
        event2 = new MappingEvent(MappingEvent.Type.MAPPING_ADD_REQUESTED, mapping2);
    }

    /**
     * Tests the equals, hashCode and toString methods using Guava EqualsTester.
     */
    @Test
    public void testEquals() {
        new EqualsTester()
                .addEqualityGroup(event1)
                .addEqualityGroup(sameAsEvent1)
                .addEqualityGroup(event2)
                .testEquals();
    }

    /**
     * Tests creation of a MappingEvent.
     */
    @Test
    public void testConstructor() {
        final long time = System.currentTimeMillis();
        final Mapping mapping = mockMapping(1, "lisp:10.1.1.1");
        final MappingEvent event = new MappingEvent(MappingEvent.Type.MAPPING_UPDATED, mapping);
        validateEvent(event, MappingEvent.Type.MAPPING_UPDATED, mapping, time,
                time + TimeUnit.SECONDS.toMillis(30));
    }
}
