package nxm.sys.inc;

import java.io.Serializable;
import java.util.Map.Entry;

import nxm.sys.lib.Table;

/** A key-value pair created using a lambda-like expression. For example:
 *  <pre>
 *    KeyValuePair p = foo-&gt;123;
 *  </pre>
 *  Creates a {@link KeyValuePair} where "foo" is the key and 123 is the value.
 *  @param <V> The value type.
 *  @author  J. Czechowski
 *  @since   NeXtMidas 3.9.0
 */
@FunctionalInterface
@SuppressWarnings("serial") // Suppress warnings about serialVersionUID, since we can't set it
public interface KeyValuePair<V> extends Serializable {
  /** This function enables the lambda expression syntax to be used to create
   *  a key-value pair <b>this should never be called directly</b>. <br>
   *  <br>
   *  The key-value pair is formed as follows:
   *  <pre>
   *    KeyValuePair p = foo-&gt;123;
   *  </pre>
   *  In this example "foo" is the key and 123 is the value.
   *  @param key When the function is called, this will always be null. However
   *             the parameter name is important since it will become the key.
   *  @return The value.
   */
  V value(Void key);

  /** Converts the {@link KeyValuePair} to an {@link Entry}.
   *  @return The entry.
   */
  @InternalUseOnly
  default Entry<String,V> toMapEntry () {
    return KeyValuePairSupport.toMapEntry(this);
  }

  /** Builds a map out of an array of {@link KeyValuePair}.
   *  @param kvPairs The array of {@link KeyValuePair}.
   *  @return The map.
   */
  @InternalUseOnly
  public static MapKBT toMap (KeyValuePair<?>... kvPairs) {
    return KeyValuePairSupport.toMap(kvPairs);
  }

  /** Builds a map out of an collection of {@link KeyValuePair}.
   *  @param kvPairs The collection of {@link KeyValuePair}.
   *  @return The map.
   */
  @InternalUseOnly
  public static MapKBT toMap (Iterable<KeyValuePair<?>> kvPairs) {
    return KeyValuePairSupport.toMap(kvPairs);
  }

  /** Builds a table out of an array of {@link KeyValuePair}. Unlike {@link #toMap}
   *  this will handle table-specific features such as converting the keys to
   *  upper-case.
   *  @param kvPairs The array of {@link KeyValuePair}.
   *  @return The table.
   */
  @InternalUseOnly
  public static Table toTable (KeyValuePair<?>... kvPairs) {
    return KeyValuePairSupport.toTable(kvPairs);
  }

  /** Builds a table out of an collection of {@link KeyValuePair}. Unlike {@link #toMap}
   *  this will handle table-specific features such as converting the keys to
   *  upper-case.
   *  @param kvPairs The collection of {@link KeyValuePair}.
   *  @return The table.
   */
  @InternalUseOnly
  public static Table toTable (Iterable<KeyValuePair<?>> kvPairs) {
    return KeyValuePairSupport.toTable(kvPairs);
  }
}
