/*
 * Copyright 2015-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.service;

import java.util.function.Function;

import org.joda.time.DateTime;
import org.onlab.util.ByteArraySizeHashPrinter;

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

/**
 * Versioned value.
 *
 * @param <V> value type.
 */
public class Versioned<V> {

    private final V value;
    private final long version;
    private final long creationTime;

    /**
     * Constructs a new versioned value.
     * @param value value
     * @param version version
     * @param creationTime milliseconds of the creation event
     *  from the Java epoch of 1970-01-01T00:00:00Z
     */
    public Versioned(V value, long version, long creationTime) {
        this.value = value;
        this.version = version;
        this.creationTime = creationTime;
    }

    /**
     * Constructs a new versioned value.
     * @param value value
     * @param version version
     */
    public Versioned(V value, long version) {
        this(value, version, System.currentTimeMillis());
    }

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

    /**
     * Returns the version.
     *
     * @return version
     */
    public long version() {
        return version;
    }

    /**
     * Returns the system time when this version was created.
     * <p>
     * Care should be taken when relying on creationTime to
     * implement any behavior in a distributed setting. Due
     * to the possibility of clock skew it is likely that
     * even creationTimes of causally related versions can be
     * out or order.
     * @return creation time
     */
    public long creationTime() {
        return creationTime;
    }

    /**
     * Maps this instance into another after transforming its
     * value while retaining the same version and creationTime.
     * @param transformer function for mapping the value
     * @param <U> value type of the returned instance
     * @return mapped instance
     */
    public synchronized <U> Versioned<U> map(Function<V, U> transformer) {
        return new Versioned<>(transformer.apply(value), version, creationTime);
    }

    /**
     * Returns the value of the specified Versioned object if non-null or else returns
     * a default value.
     * @param versioned versioned object
     * @param defaultValue default value to return if versioned object is null
     * @param <U> type of the versioned value
     * @return versioned value or default value if versioned object is null
     */
    public static <U> U valueOrElse(Versioned<U> versioned, U defaultValue) {
        return versioned == null ? defaultValue : versioned.value();
    }

    /**
     * Returns the value of the specified Versioned object if non-null or else returns null.
     * @param versioned versioned object
     * @param <U> type of the versioned value
     * @return versioned value or null if versioned object is null
     */
    public static <U> U valueOrNull(Versioned<U> versioned) {
        return valueOrElse(versioned, null);
    }

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

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof Versioned)) {
            return false;
        }
        Versioned<V> that = (Versioned) other;
        return Objects.equal(this.value, that.value) &&
               Objects.equal(this.version, that.version) &&
               Objects.equal(this.creationTime, that.creationTime);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
            .add("value", value instanceof byte[] ? new ByteArraySizeHashPrinter((byte[]) value) : value)
            .add("version", version)
            .add("creationTime", new DateTime(creationTime))
            .toString();
    }
}
