/*
 * Copyright 2018-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.atomix.primitives.impl;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.onosproject.store.Timestamp;

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

/**
 * Representation of a value in EventuallyConsistentMap.
 *
 * @param <V> value type
 */
public class MapValue<V> implements Comparable<MapValue<V>> {
    private final Timestamp timestamp;
    private final V value;
    private long creationTime;

    /**
     * Creates a tombstone value with the specified timestamp.
     *
     * @param timestamp timestamp for tombstone
     * @return tombstone MapValue
     *
     * @param <U> value type
     */
    public static <U> MapValue<U> tombstone(Timestamp timestamp) {
        return new MapValue<>(null, timestamp, System.currentTimeMillis());
    }

    /**
     * Constructor automatically to create the system time of construction.
     *
     * @param value value
     * @param timestamp value timestamp
     */
    public MapValue(V value, Timestamp timestamp) {
        this(value, timestamp, System.currentTimeMillis());
    }

    /**
     * Creates a map value using value, timestamp, and creation time.
     *
     * @param value value
     * @param timestamp value timestamp.
     * @param creationTime the system time (on local instance) of construction
     */
    public MapValue(V value, Timestamp timestamp, long creationTime) {
        this.value = value;
        this.timestamp = checkNotNull(timestamp, "Timestamp cannot be null");
        this.creationTime = creationTime;
    }

    /**
     * Creates a copy of MapValue.
     * <p>
     * The copy will have an updated creation time corresponding to when the copy was constructed.
     *
     * @return MapValue copy
     */
    public MapValue<V> copy() {
        return new MapValue<>(this.value, this.timestamp, System.currentTimeMillis());
    }

    /**
     * Tests if this value is tombstone value with the specified timestamp.
     *
     * @return true if this value is null, otherwise false
     */
    public boolean isTombstone() {
        return value == null;
    }

    /**
     * Tests if this value is alive.
     *
     * @return true if this value is not null, otherwise false
     */
    public boolean isAlive() {
        return value != null;
    }

    /**
     * Returns the timestamp of this value.
     *
     * @return timestamp
     */
    public Timestamp timestamp() {
        return timestamp;
    }

    /**
     * Returns this value.
     *
     * @return value
     */
    public V get() {
        return value;
    }

    /**
     * Returns the creation time of this value.
     *
     * @return creationTime
     */
    public long creationTime() {
        return creationTime;
    }

    /**
     * Tests if this value is newer than the specified MapValue.
     *
     * @param other the value to be compared
     * @return true if this value is newer than other
     */
    public boolean isNewerThan(MapValue<V> other) {
        if (other == null) {
            return true;
        }
        return this.timestamp.isNewerThan(other.timestamp);
    }

    /**
     * Tests if this timestamp is newer than the specified timestamp.
     *
     * @param timestamp timestamp to be compared
     * @return true if this instance is newer
     */
    public boolean isNewerThan(Timestamp timestamp) {
        return this.timestamp.isNewerThan(timestamp);
    }

    /**
     * Returns summary of a MapValue for use during Anti-Entropy exchanges.
     *
     * @return Digest with timestamp and whether this value is null or not
     */
    public Digest digest() {
        return new Digest(timestamp, isTombstone());
    }

    @Override
    public int compareTo(MapValue<V> o) {
        return this.timestamp.compareTo(o.timestamp);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(timestamp, value);
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean equals(Object other) {
        if (other instanceof MapValue) {
            MapValue<V> that = (MapValue<V>) other;
            return Objects.equal(this.timestamp, that.timestamp) &&
                    Objects.equal(this.value, that.value);
        }
        return false;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("timestamp", timestamp)
                .add("value", value)
                .toString();
    }

    @SuppressWarnings("unused")
    private MapValue() {
        this.timestamp = null;
        this.value = null;
    }

    /**
     * Digest or summary of a MapValue for use during Anti-Entropy exchanges.
     */
    public static class Digest {
        private final Timestamp timestamp;
        private final boolean isTombstone;

        public Digest(Timestamp timestamp, boolean isTombstone) {
            this.timestamp = timestamp;
            this.isTombstone = isTombstone;
        }

        public Timestamp timestamp() {
            return timestamp;
        }

        public boolean isTombstone() {
            return isTombstone;
        }

        public boolean isNewerThan(Digest other) {
            return timestamp.isNewerThan(other.timestamp);
        }

        @Override
        public int hashCode() {
            return Objects.hashCode(timestamp, isTombstone);
        }

        @Override
        public boolean equals(Object other) {
            if (other instanceof Digest) {
                Digest that = (Digest) other;
                return Objects.equal(this.timestamp, that.timestamp) &&
                        Objects.equal(this.isTombstone, that.isTombstone);
            }
            return false;
        }

        @Override
        public String toString() {
            return MoreObjects.toStringHelper(getClass())
                    .add("timestamp", timestamp)
                    .add("isTombstone", isTombstone)
                    .toString();
        }
    }
}
