/*
 * Copyright 2015 Google Inc.
 *
 * 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 java.util;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

import static javaemul.internal.InternalPreconditions.checkCriticalElement;
import static javaemul.internal.InternalPreconditions.checkCriticalNotNull;
import static javaemul.internal.InternalPreconditions.checkNotNull;

/**
 * See <a href="https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html">
 * the official Java API doc</a> for details.
 *
 * @param <T> type of the wrapped reference
 */
public final class Optional<T> {

  @SuppressWarnings("unchecked")
  public static <T> Optional<T> empty() {
    return (Optional<T>) EMPTY;
  }

  public static <T> Optional<T> of(T value) {
    return new Optional<>(checkCriticalNotNull(value));
  }

  public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
  }

  private static final Optional<?> EMPTY = new Optional<>(null);

  private final T ref;

  private Optional(T ref) {
    this.ref = ref;
  }

  public boolean isPresent() {
    return ref != null;
  }

  public boolean isEmpty() {
    return ref == null;
  }

  public T get() {
    checkCriticalElement(isPresent());
    return ref;
  }

  public void ifPresent(Consumer<? super T> consumer) {
    if (isPresent()) {
      consumer.accept(ref);
    }
  }

  public Optional<T> filter(Predicate<? super T> predicate) {
    checkNotNull(predicate);
    if (!isPresent() || predicate.test(ref)) {
      return this;
    }
    return empty();
  }

  public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    checkNotNull(mapper);
    if (isPresent()) {
      return ofNullable(mapper.apply(ref));
    }
    return empty();
  }

  public <U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    checkNotNull(mapper);
    if (isPresent()) {
      return checkNotNull(mapper.apply(ref));
    }
    return empty();
  }

  public T orElse(T other) {
    return isPresent() ? ref : other;
  }

  public T orElseGet(Supplier<? extends T> other) {
    return isPresent() ? ref : other.get();
  }

  public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
    if (isPresent()) {
      return ref;
    }
    throw exceptionSupplier.get();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == this) {
      return true;
    }
    if (!(obj instanceof Optional)) {
      return false;
    }
    Optional<?> other = (Optional<?>) obj;
    return Objects.equals(ref, other.ref);
  }

  @Override
  public int hashCode() {
    return Objects.hashCode(ref);
  }

  @Override
  public String toString() {
    return isPresent() ? "Optional.of(" + String.valueOf(ref) + ")" : "Optional.empty()";
  }
}
