/*
 * Copyright 2015-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.store.service;

import java.util.Objects;

import com.google.common.base.MoreObjects;

/**
 * Representation of a ConsistentMap update notification.
 *
 * @param <K> key type
 * @param <V> value type
 */
public class MapEvent<K, V> {

    /**
     * MapEvent type.
     */
    public enum Type {
        /**
         * Entry inserted into the map.
         */
        INSERT,

        /**
         * Existing map entry updated.
         */
        UPDATE,

        /**
         * Entry removed from map.
         */
        REMOVE
    }

    private final String name;
    private final Type type;
    private final K key;
    private final Versioned<V> newValue;
    private final Versioned<V> oldValue;

    /**
     * Creates a new event object.
     *
     * @param name map name
     * @param key key the event concerns
     * @param currentValue new value key is mapped to
     * @param previousValue value that was replaced
     */
    public MapEvent(String name, K key, Versioned<V> currentValue, Versioned<V> previousValue) {
        this.name = name;
        this.key = key;
        this.newValue = currentValue;
        this.oldValue = previousValue;
        this.type = currentValue != null ?
                    previousValue != null ? Type.UPDATE : Type.INSERT : Type.REMOVE;
    }

    /**
     * Returns the map name.
     *
     * @return name of map
     */
    public String name() {
        return name;
    }

    /**
     * Returns the type of the event.
     *
     * @return the type of event
     */
    public Type type() {
        return type;
    }

    /**
     * Returns the key this event concerns.
     *
     * @return the key
     */
    public K key() {
        return key;
    }

    /**
     * Returns the value associated with this event. If type is REMOVE,
     * this is the value that was removed. If type is INSERT/UPDATE, this is
     * the new value.
     *
     * @return the value
     * @deprecated 1.5.0 Falcon release. Use {@link #newValue()} or {@link #oldValue()} instead.
     */
    @Deprecated
    public Versioned<V> value() {
        return type == Type.REMOVE ? oldValue() : newValue();
    }

    /**
     * Returns the new value in the map associated with the key. If {@link #type()} returns {@code REMOVE},
     * this method will return {@code null}.
     *
     * @return the new value for key
     */
    public Versioned<V> newValue() {
        return newValue;
    }

    /**
     * Returns the value associated with the key, before it was updated.
     *
     * @return previous value in map for the key
     */
    public Versioned<V> oldValue() {
        return oldValue;
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof MapEvent)) {
            return false;
        }

        MapEvent<K, V> that = (MapEvent) o;
        return Objects.equals(this.name, that.name) &&
                Objects.equals(this.type, that.type) &&
                Objects.equals(this.key, that.key) &&
                Objects.equals(this.newValue, that.newValue) &&
                Objects.equals(this.oldValue, that.oldValue);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, type, key, newValue, oldValue);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("name", name)
                .add("type", type)
                .add("key", key)
                .add("newValue", newValue)
                .add("oldValue", oldValue)
                .toString();
    }
}
