package org.checkerframework.checker.nullness.util;

import java.util.NoSuchElementException;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.checkerframework.checker.nullness.qual.EnsuresNonNullIf;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.framework.qual.AnnotatedFor;

/**
 * Utility class for the Nullness Checker, providing every method in {@link java.util.Optional}, but
 * written for possibly-null references rather than for the {@code Optional} type.
 *
 * <p>To avoid the need to write the {@code Opt} class name at invocation sites, do:
 *
 * <pre>import static org.checkerframework.checker.nullness.util.Opt.orElse;</pre>
 *
 * or
 *
 * <pre>import static org.checkerframework.checker.nullness.util.Opt.*;</pre>
 *
 * <p><b>Runtime Dependency</b>: If you use this class, you must distribute (or link to) {@code
 * checker-qual.jar}, along with your binaries. Or, you can can copy this class into your own
 * project.
 *
 * @see java.util.Optional
 */
@AnnotatedFor("nullness")
public final class Opt {

  /** The Opt class cannot be instantiated. */
  private Opt() {
    throw new AssertionError("shouldn't be instantiated");
  }

  /**
   * If primary is non-null, returns it, otherwise throws NoSuchElementException.
   *
   * @param <T> the type of the argument
   * @param primary a non-null value to return
   * @return {@code primary} if it is non-null
   * @throws NoSuchElementException if primary is null
   * @see java.util.Optional#get()
   */
  // `primary` is @NonNull; otherwise, the method could throw an exception.
  public static <T extends @NonNull Object> T get(T primary) {
    if (primary == null) {
      throw new NoSuchElementException("No value present");
    }
    return primary;
  }

  /**
   * Returns true if primary is non-null, false if primary is null.
   *
   * @see java.util.Optional#isPresent()
   */
  @EnsuresNonNullIf(expression = "#1", result = true)
  public static boolean isPresent(@Nullable Object primary) {
    return primary != null;
  }

  /**
   * If primary is non-null, invoke the specified consumer with the value, otherwise do nothing.
   *
   * @see java.util.Optional#ifPresent(Consumer)
   */
  public static <T> void ifPresent(T primary, Consumer<@NonNull ? super @NonNull T> consumer) {
    if (primary != null) {
      consumer.accept(primary);
    }
  }

  /**
   * If primary is non-null, and its value matches the given predicate, return the value. If primary
   * is null or its non-null value does not match the predicate, return null.
   *
   * @see java.util.Optional#filter(Predicate)
   */
  public static <T> @Nullable T filter(
      T primary, Predicate<@NonNull ? super @NonNull T> predicate) {
    if (primary == null) {
      return null;
    } else {
      return predicate.test(primary) ? primary : null;
    }
  }

  /**
   * If primary is non-null, apply the provided mapping function to it and return the result. If
   * primary is null, return null.
   *
   * @see java.util.Optional#map(Function)
   */
  public static <T, U> @Nullable U map(
      T primary, Function<@NonNull ? super @NonNull T, ? extends U> mapper) {
    if (primary == null) {
      return null;
    } else {
      return mapper.apply(primary);
    }
  }

  // flatMap would have the same signature and implementation as map

  /**
   * Return primary if it is non-null. If primary is null, return other.
   *
   * @see java.util.Optional#orElse(Object)
   */
  public static <T> @NonNull T orElse(T primary, @NonNull T other) {
    return primary != null ? primary : other;
  }

  /**
   * Return primary if it is non-null. If primary is null, invoke {@code other} and return the
   * result of that invocation.
   *
   * @see java.util.Optional#orElseGet(Supplier)
   */
  public static <T> @NonNull T orElseGet(T primary, Supplier<? extends @NonNull T> other) {
    return primary != null ? primary : other.get();
  }

  /**
   * Return primary if it is non-null. If primary is null, throw an exception to be created by the
   * provided supplier.
   *
   * @see java.util.Optional#orElseThrow(Supplier)
   */
  // `primary` is @NonNull; otherwise, the method could throw an exception.
  public static <T extends @NonNull Object, X extends @NonNull Throwable> T orElseThrow(
      T primary, Supplier<? extends X> exceptionSupplier) throws X {
    if (primary != null) {
      return primary;
    } else {
      throw exceptionSupplier.get();
    }
  }
}
