/*
 * Copyright 2015 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.primitives.resources.impl;

import com.google.common.testing.EqualsTester;
import org.junit.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;

/**
 * Unit Tests for MapUpdate class.
 */

public class MapUpdateTest {

    private final MapUpdate<String, byte[]> stats1 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.PUT)
            .build();

    private final MapUpdate<String, byte[]> stats2 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.REMOVE)
            .build();

    private final MapUpdate<String, byte[]> stats3 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.REMOVE_IF_VALUE_MATCH)
            .build();

    private final MapUpdate<String, byte[]> stats4 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.REMOVE_IF_VERSION_MATCH)
            .build();

    private final MapUpdate<String, byte[]> stats5 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.PUT_IF_VALUE_MATCH)
            .build();

    private final MapUpdate<String, byte[]> stats6 = MapUpdate.<String, byte[]>newBuilder()
            .withCurrentValue("1".getBytes())
            .withValue("2".getBytes())
            .withCurrentVersion(3)
            .withKey("4")
            .withMapName("5")
            .withType(MapUpdate.Type.PUT_IF_VERSION_MATCH)
            .build();

    /**
     *  Tests the constructor for the class.
     */
    @Test
    public void testConstruction() {
        assertThat(stats1.currentValue(), is("1".getBytes()));
        assertThat(stats1.value(), is("2".getBytes()));
        assertThat(stats1.currentVersion(), is(3L));
        assertThat(stats1.key(), is("4"));
        assertThat(stats1.mapName(), is("5"));
        assertThat(stats1.type(), is(MapUpdate.Type.PUT));
    }

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

        new EqualsTester()
                .addEqualityGroup(stats3, stats3)
                .addEqualityGroup(stats4)
                .testEquals();

        new EqualsTester()
                .addEqualityGroup(stats5, stats5)
                .addEqualityGroup(stats6)
                .testEquals();
    }

    /**
     * Tests if the toString method returns a consistent value for hashing.
     */
    @Test
    public void testToString() {
        assertThat(stats1.toString(), is(stats1.toString()));
    }

}
