/*
 * Copyright 2017-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;
import org.onosproject.store.service.DocumentPath;

/**
 * DocumentTree node update operation.
 *
 * @param <V> map value type
 */
public final class NodeUpdate<V> {

    /**
     * Type of database update operation.
     */
    public enum Type {
        // FIXME revisit these, mismatch in description and actual implementation
        // Also, type of update operations probably insufficient.
        /**
         * Creates an entry if the current version matches specified version.
         */
        CREATE_NODE,
        /**
         * Updates an entry if the current version matches specified version.
         */
        UPDATE_NODE,
        /**
         * Deletes an entry if the current version matches specified version.
         */
        DELETE_NODE
    }

    private Type type;
    private DocumentPath path;
    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 path being updated.
     * @return item path
     */
    public DocumentPath path() {
        return path;
    }

    /**
     * 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 valueMapper transcoder to value type
     * @return new instance
     * @param <T> value type of returned instance
     */
    public <T> NodeUpdate<T> map(Function<V, T> valueMapper) {
        return NodeUpdate.<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, path, value, version);
    }

    @Override
    public boolean equals(Object object) {
        if (object instanceof NodeUpdate) {
            NodeUpdate that = (NodeUpdate) object;
            return this.type == that.type
                    && Objects.equals(this.path, that.path)
                    && 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("path", path)
                .add("value", value instanceof byte[] ?
                        new ByteArraySizeHashPrinter((byte[]) value) : value)
                .add("version", version)
                .toString();
    }

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

    /**
     * NodeUpdate builder.
     *
     * @param <V> value type
     */
    public static final class Builder<V> {

        private NodeUpdate<V> update = new NodeUpdate<>();

        public NodeUpdate<V> build() {
            validateInputs();
            return update;
        }

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

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

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

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

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

        }
    }
}
