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