
/*
 * 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 java.util.function.Function;

import org.onosproject.store.service.MapEvent;
import org.onosproject.store.service.Versioned;

import com.google.common.base.MoreObjects;

/**
 * Result of a map entry update operation.
 * <p>
 * Both old and new values are accessible along with a flag that indicates if the
 * the value was updated. If flag is false, oldValue and newValue both
 * point to the same unmodified value.
 *
 * @param <K> key type
 * @param <V> result type
 */
public class MapEntryUpdateResult<K, V> {

    public enum Status {

        /**
         * Indicates a successful update.
         */
        OK,

        /**
         * Indicates a noop i.e. existing and new value are both null.
         */
        NOOP,

        /**
         * Indicates a failed update due to a write lock.
         */
        WRITE_LOCK,

        /**
         * Indicates a failed update due to a precondition check failure.
         */
        PRECONDITION_FAILED
    }

    private final String mapName;
    private Status status;
    private final K key;
    private final Versioned<V> oldValue;
    private final Versioned<V> newValue;

    public MapEntryUpdateResult(Status status, String mapName, K key, Versioned<V> oldValue, Versioned<V> newValue) {
        this.status = status;
        this.mapName = mapName;
        this.key = key;
        this.oldValue = oldValue;
        this.newValue = newValue;
    }

    /**
     * Returns {@code true} if the update was successful.
     * @return {@code true} if yes, {@code false} otherwise
     */
    public boolean updated() {
        return status == Status.OK;
    }

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

    /**
     * Returns the update status.
     * @return update status
     */
    public Status status() {
        return status;
    }

    /**
     * Returns the map key.
     * @return key
     */
    public K key() {
        return key;
    }

    /**
     * Returns the old value.
     * @return the previous value associated with key if updated was successful, otherwise current value
     */
    public Versioned<V> oldValue() {
        return oldValue;
    }

    /**
     * Returns the new value after update.
     * @return if updated was unsuccessful, this is same as old value
     */
    public Versioned<V> newValue() {
        return newValue;
    }

    /**
     * Maps to another instance with different key and value types.
     * @param keyTransform transformer to use for transcoding keys
     * @param valueMapper mapper to use for transcoding values
     * @return new instance
     * @param <K1> key type of returned {@code MapEntryUpdateResult}
     * @param <V1> value type of returned {@code MapEntryUpdateResult}
     */
    public <K1, V1> MapEntryUpdateResult<K1, V1> map(Function<K, K1> keyTransform, Function<V, V1> valueMapper) {
        return new MapEntryUpdateResult<>(status,
                mapName,
                keyTransform.apply(key),
                oldValue == null ? null : oldValue.map(valueMapper),
                newValue == null ? null : newValue.map(valueMapper));
    }

    /**
     * Return the map event that will be generated as a result of this update.
     * @return map event. if update was unsuccessful, this returns {@code null}
     */
    public MapEvent<K, V> toMapEvent() {
        if (!updated()) {
            return null;
        } else {
            return new MapEvent<>(mapName(), key(), newValue, oldValue);
        }
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(MapEntryUpdateResult.class)
                .add("mapName", mapName)
                .add("status", status)
                .add("key", key)
                .add("oldValue", oldValue)
                .add("newValue", newValue)
                .toString();
    }
}
