/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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 org.onosproject.store.Timestamp;

import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;

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

    public MapValue(V value, Timestamp timestamp) {
        this(value, timestamp, System.currentTimeMillis());
    }

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

    public boolean isTombstone() {
        return value == null;
    }

    public boolean isAlive() {
        return value != null;
    }

    public Timestamp timestamp() {
        return timestamp;
    }

    public V get() {
        return value;
    }

    public long creationTime() {
        return creationTime;
    }

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

    public boolean isNewerThan(MapValue<V> other) {
        if (other == null) {
            return true;
        }
        return this.timestamp.isNewerThan(other.timestamp);
    }

    public boolean isNewerThan(Timestamp timestamp) {
        return this.timestamp.isNewerThan(timestamp);
    }

    public Digest digest() {
        return new Digest(timestamp, isTombstone());
    }

    @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();
        }
    }
}
