/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import java.util.Objects;
import java.util.function.Function;

import org.onlab.util.ByteArraySizeHashPrinter;

import com.google.common.base.MoreObjects;

/**
 * Map update operation.
 *
 * @param <K> map key type
 * @param <V> map value type
 */
public final class MapUpdate<K, V> {

    /**
     * Type of database update operation.
     */
    public enum Type {

        /**
         * Acquires a read lock on a key.
         * <p>
         * This record type will check to ensure that the lock version matches the current version for the key
         * in the map and acquire a read lock on the key for the duration of the transaction.
         */
        LOCK,

        /**
         * Checks the version of a key without locking the key.
         * <p>
         * This record type will perform a simple version check during the prepare phase of the two-phase commit
         * protocol to ensure that the key has not changed during a transaction.
         */
        VERSION_MATCH,

        /**
         * Updates an entry if the current version matches specified version.
         */
        PUT_IF_VERSION_MATCH,

        /**
         * Removes an entry if the current version matches specified version.
         */
        REMOVE_IF_VERSION_MATCH,
    }

    private Type type;
    private K key;
    private V value;
    private long version = -1;

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

    /**
     * Returns the item key being updated.
     * @return item key
     */
    public K key() {
        return key;
    }

    /**
     * Returns the new value.
     * @return item's target value.
     */
    public V value() {
        return value;
    }

    /**
     * Returns the expected current version in the database for the key.
     * @return expected version.
     */
    public long version() {
        return version;
    }

    /**
     * Transforms this instance into an instance of different parameterized types.
     *
     * @param keyMapper transcoder for key type
     * @param valueMapper transcoder to value type
     * @return new instance
     * @param <S> key type of returned instance
     * @param <T> value type of returned instance
     */
    public <S, T> MapUpdate<S, T> map(Function<K, S> keyMapper, Function<V, T> valueMapper) {
        return MapUpdate.<S, T>newBuilder()
                .withType(type)
                .withKey(keyMapper.apply(key))
                .withValue(value == null ? null : valueMapper.apply(value))
                .withVersion(version)
                .build();
    }

    @Override
    public int hashCode() {
        return Objects.hash(type, key, value, version);
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof MapUpdate) {
            MapUpdate that = (MapUpdate) object;
            return this.type == that.type
                    && Objects.equals(this.key, that.key)
                    && Objects.equals(this.value, that.value)
                    && Objects.equals(this.version, that.version);
        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("type", type)
            .add("key", key)
            .add("value", value instanceof byte[] ? new ByteArraySizeHashPrinter((byte[]) value) : value)
            .add("version", version)
            .toString();
    }

    /**
     * Creates a new builder instance.
     *
     * @param <K> key type
     * @param <V> value type
     * @return builder.
     */
    public static <K, V> Builder<K, V> newBuilder() {
        return new Builder<>();
    }

    /**
     * MapUpdate builder.
     *
     * @param <K> key type
     * @param <V> value type
     */
    public static final class Builder<K, V> {

        private MapUpdate<K, V> update = new MapUpdate<>();

        public MapUpdate<K, V> build() {
            validateInputs();
            return update;
        }

        public Builder<K, V> withType(Type type) {
            update.type = checkNotNull(type, "type cannot be null");
            return this;
        }

        public Builder<K, V> withKey(K key) {
            update.key = checkNotNull(key, "key cannot be null");
            return this;
        }

        public Builder<K, V> withValue(V value) {
            update.value = value;
            return this;
        }

        public Builder<K, V> withVersion(long version) {
            update.version = version;
            return this;
        }

        private void validateInputs() {
            checkNotNull(update.type, "type must be specified");
            switch (update.type) {
                case VERSION_MATCH:
                    break;
                case LOCK:
                    checkNotNull(update.key, "key must be specified");
                    checkState(update.version >= 0, "version must be specified");
                    break;
                case PUT_IF_VERSION_MATCH:
                    checkNotNull(update.key, "key must be specified");
                    checkNotNull(update.value, "value must be specified.");
                    checkState(update.version >= 0, "version must be specified");
                    break;
                case REMOVE_IF_VERSION_MATCH:
                    checkNotNull(update.key, "key must be specified");
                    checkState(update.version >= 0, "version must be specified");
                    break;
                default:
                    throw new IllegalStateException("Unknown operation type");
            }

        }
    }
}
