package org.onlab.onos.store.service;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.onos.store.service.WriteRequest.Type.*;

import java.util.Objects;

import org.onlab.util.ByteArraySizeHashPrinter;

import com.google.common.base.MoreObjects;

/**
 * Database write request.
 */
public class WriteRequest {

    public static final int ANY_VERSION = -1;

    private final String tableName;
    private final String key;

    private final Type type;

    private final byte[] newValue;
    private final long previousVersion;
    private final byte[] oldValue;

    /**
     * Creates a write request, which will
     * put the specified value to the table regardless of the previous value.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param newValue  value to write, must not be null
     * @return WriteRequest
     */
    public static WriteRequest put(String tableName, String key,
                                   byte[] newValue) {
        return new WriteRequest(PUT, tableName, key,
                                checkNotNull(newValue), ANY_VERSION, null);
    }

    /**
     * Creates a write request, which will
     * put the specified value to the table if the previous version matches.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param newValue  value to write, must not be null
     * @param previousVersion previous version expected
     * @return WriteRequest
     */
    public static WriteRequest putIfVersionMatches(String tableName, String key,
                                                   byte[] newValue,
                                                   long previousVersion) {
        checkArgument(previousVersion >= 0);
        return new WriteRequest(PUT_IF_VERSION, tableName, key,
                                checkNotNull(newValue), previousVersion, null);
    }

    /**
     * Creates a write request, which will
     * put the specified value to the table if the previous value matches.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param oldValue  previous value expected, must not be null
     * @param newValue  value to write, must not be null
     * @return WriteRequest
     */
    public static WriteRequest putIfValueMatches(String tableName, String key,
                                                 byte[] oldValue,
                                                 byte[] newValue) {
        return new WriteRequest(PUT_IF_VALUE, tableName, key,
                                checkNotNull(newValue), ANY_VERSION,
                                checkNotNull(oldValue));
    }

    /**
     * Creates a write request, which will
     * put the specified value to the table if the previous value does not exist.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param newValue  value to write, must not be null
     * @return WriteRequest
     */
    public static WriteRequest putIfAbsent(String tableName, String key,
                                           byte[] newValue) {
        return new WriteRequest(PUT_IF_ABSENT, tableName, key,
                                checkNotNull(newValue), ANY_VERSION, null);
    }

    /**
     * Creates a write request, which will
     * remove the specified entry from the table regardless of the previous value.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @return WriteRequest
     */
    public static WriteRequest remove(String tableName, String key) {
        return new WriteRequest(REMOVE, tableName, key,
                                null, ANY_VERSION, null);
    }

    /**
     * Creates a write request, which will
     * remove the specified entry from the table if the previous version matches.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param previousVersion previous version expected
     * @return WriteRequest
     */
    public static WriteRequest removeIfVersionMatches(String tableName, String key,
                                      long previousVersion) {
        return new WriteRequest(REMOVE_IF_VERSION, tableName, key,
                                null, previousVersion, null);
    }

    /**
     * Creates a write request, which will
     * remove the specified entry from the table if the previous value matches.
     *
     * @param tableName name of the table
     * @param key       key in the table
     * @param oldValue  previous value expected, must not be null
     * @return WriteRequest
     */
    public static WriteRequest removeIfValueMatches(String tableName, String key,
                                      byte[] oldValue) {
        return new WriteRequest(REMOVE_IF_VALUE, tableName, key,
                                null, ANY_VERSION, checkNotNull(oldValue));
    }

    public enum Type {
        PUT,
        PUT_IF_VERSION,
        PUT_IF_VALUE,
        PUT_IF_ABSENT,
        REMOVE,
        REMOVE_IF_VERSION,
        REMOVE_IF_VALUE,
    }

    // hidden constructor
    protected WriteRequest(Type type, String tableName, String key,
                           byte[] newValue,
                           long previousVersion, byte[] oldValue) {

        checkNotNull(tableName);
        checkNotNull(key);

        this.tableName = tableName;
        this.key = key;
        this.type = type;
        this.newValue = newValue;
        this.previousVersion = previousVersion;
        this.oldValue = oldValue;
    }

    public String tableName() {
        return tableName;
    }

    public String key() {
        return key;
    }

    public WriteRequest.Type type() {
        return type;
    }

    public byte[] newValue() {
        return newValue;
    }

    public long previousVersion() {
        return previousVersion;
    }

    public byte[] oldValue() {
        return oldValue;
    }

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

    // TODO: revisit hashCode, equals condition
    @Override
    public int hashCode() {
        return Objects.hash(type, key, tableName, previousVersion);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        WriteRequest other = (WriteRequest) obj;
        return Objects.equals(this.type, other.type) &&
                Objects.equals(this.key, other.key) &&
                Objects.equals(this.tableName, other.tableName) &&
                Objects.equals(this.previousVersion, other.previousVersion);
    }
}
