
/*
 * 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 <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
     */
    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();
    }
}
