package org.infinispan.stats;

import org.infinispan.commons.dataconversion.internal.Json;
import org.infinispan.commons.dataconversion.internal.JsonSerialization;

/**
 * Stats.
 *
 * @author Galder Zamarreño
 * @since 4.0
 */
public interface Stats extends JsonSerialization {

   @Override
   default Json toJson() {
      return Json.object()
            .set("time_since_start", getTimeSinceStart())
            .set("time_since_reset", getTimeSinceReset())
            .set("approximate_entries", getApproximateEntries())
            .set("approximate_entries_in_memory", getApproximateEntriesInMemory())
            .set("approximate_entries_unique", getApproximateEntriesUnique())
            .set("current_number_of_entries", getCurrentNumberOfEntries())
            .set("current_number_of_entries_in_memory", getCurrentNumberOfEntriesInMemory())
            .set("off_heap_memory_used", getOffHeapMemoryUsed())
            .set("data_memory_used", getDataMemoryUsed())
            .set("stores", getStores())
            .set("retrievals", getRetrievals())
            .set("hits", getHits())
            .set("misses", getMisses())
            .set("remove_hits", getRemoveHits())
            .set("remove_misses", getRemoveMisses())
            .set("evictions", getEvictions())
            .set("average_read_time", getAverageReadTime())
            .set("average_read_time_nanos", getAverageReadTimeNanos())
            .set("average_write_time", getAverageWriteTime())
            .set("average_write_time_nanos", getAverageRemoveTimeNanos())
            .set("average_remove_time", getAverageRemoveTime())
            .set("average_remove_time_nanos", getAverageRemoveTimeNanos())
            .set("required_minimum_number_of_nodes", getRequiredMinimumNumberOfNodes());
   }

   /**
    * @return Number of seconds since cache started.
    */
   long getTimeSinceStart();

   /**
    * @return Number of seconds since stats where reset
    */
   long getTimeSinceReset();

   /**
    * Returns the approximate number of entries in this cache that exist in memory or persistent storage.
    *
    * When the cache is configured with distribution, this method only returns the
    * number of entries in the local cache instance. In other words, it does
    * not communicate with other nodes to find out about data
    * stored in the cluster and not available locally.
    *
    * @return Number of entries currently in the cache, including passivated entries.
    */
   long getApproximateEntries();

   /**
    * The same as {@link #getApproximateEntries()}, however passivated entries are not included.
    */
   long getApproximateEntriesInMemory();

   /**
    * The same as {@link #getApproximateEntries()}, however only entries owned as primary are counted.
    *
    * This is only different from {@link #getApproximateEntries()} only in distributed and replicated caches.
    */
   long getApproximateEntriesUnique();

   /**
    * Returns the number of entries currently in this cache instance. When
    * the cache is configured with distribution, this method only returns the
    * number of entries in the local cache instance. In other words, it does
    * not attempt to communicate with other nodes to find out about the data
    * stored in other nodes in the cluster that is not available locally.
    *
    * @return Number of entries currently in the cache, including passivated entries.
    * @deprecated Since 14.0, please use {@link #getApproximateEntries()} or {@link #getApproximateEntriesUnique()} instead.
    */
   @Deprecated(forRemoval=true, since = "14.0")
   int getCurrentNumberOfEntries();

   /**
    * The same as {@link #getCurrentNumberOfEntries()}, however passivated entries are not included.
    * @deprecated Since 14.0, please use {@link #getApproximateEntriesInMemory()} instead.
    */
   @Deprecated(forRemoval=true, since = "14.0")
   int getCurrentNumberOfEntriesInMemory();

   /**
    * The amount of off-heap memory used by this cache, or -1 if the cache stores data in the heap.
    */
   long getOffHeapMemoryUsed();

   /**
    * Provides how much memory the current eviction algorithm estimates is in use for data. This method will return a
    * number 0 or greater if memory eviction is in use. If memory eviction is not enabled this method will always return -1.
    * @return memory in use or -1 if memory eviction is not enabled
    */
   long getDataMemoryUsed();

   /**
    * @return Number of entries stored in cache since start.
    */
   long getStores();

   /**
    * @return Number of entries read from the cache since start.
    */
   long getRetrievals();

   /**
    * @return Number of cache get hits.
    */
   long getHits();

   /**
    * @return Number of cache get misses.
    */
   long getMisses();

   /**
    * @return Number of cache removal hits.
    */
   long getRemoveHits();

   /**
    * @return Number of cache removal misses.
    */
   long getRemoveMisses();

   /**
    * @return Number of cache eviction.
    */
   long getEvictions();

   /**
    * @return Average number of milliseconds for a cache get on the cache
    */
   long getAverageReadTime();

   /**
    * @return Average number of nanoseconds for a cache get on the cache
    */
   long getAverageReadTimeNanos();

   /**
    * @return Average number of milliseconds for a cache put on the cache
    * @deprecated Since 14.0, please use {@link #getAverageReadTimeNanos()} instead.
    */
   @Deprecated(forRemoval=true, since = "14.0")
   long getAverageWriteTime();

   /**
    * @return Average number of milliseconds for a cache put on the cache
    */
   long getAverageWriteTimeNanos();

   /**
    * @return Average number of milliseconds for a cache remove on the cache
    * @deprecated Since 14.0, please use {@link #getAverageWriteTimeNanos()} instead.
    */
   @Deprecated(forRemoval=true, since = "14.0")
   long getAverageRemoveTime();

   /**
    * @return Average number of nanoseconds for a cache remove on the cache
    */
   long getAverageRemoveTimeNanos();

   /**
    * @return Required minimum number of nodes to guarantee data consistency
    */
   int getRequiredMinimumNumberOfNodes();

   /**
    * Reset statistics
    */
   void reset();

   /**
    * Enables or disables statistics at runtime.
    *
    * @param enabled boolean indicating whether statistics should be enable or not
    */
   void setStatisticsEnabled(boolean enabled);

}
