// Copyright 2018 The Bazel Authors. All rights reserved.
//
// 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 com.google.devtools.build.lib.util;

import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * A container wrapping a value of one of two types. An {@code Either<A, B>} instance either wraps
 * an instance of {@code A} or a instance of {@code B}.
 *
 * <p>Just as with {@link Pair}, this class is immutable, supports nullable values, and is
 * completely devoid of Bazel-business-logic-specific semantics. Avoid using it in public APIs.
 *
 * <p>This class is a simple implementation of a general purpose "sum" type. In type theory, sum
 * types are the duals of product types -- the corresponding observation here is that {@link Either}
 * is the dual of {@link Pair}.
 */
public abstract class Either<A, B> {
  // Disallow subclasses outside of this file.
  private Either() {
  }

  /** Constructs a {@link Either} representing the left injection of {@code a}. */
  public static <A, B> Either<A, B> ofLeft(A a) {
    return new LeftEither<>(a);
  }

  /** Constructs a {@link Either} representing the right injection of {@code b}. */
  public static <A, B> Either<A, B> ofRight(B b) {
    return new RightEither<>(b);
  }

  /**
   * Consumes the value injected into this {@link Either}. A left injection is consumed using
   * {@code leftConsumer} and a right injection is consumed using {@code rightConsumer}.
   */
  public abstract void consume(Consumer<A> leftConsumer, Consumer<B> rightConsumer);

  /**
   * Maps the value injected into this {@link Either}. A left injection is mapped using
   * {@code leftFunction} and a right injection is mapped using {@code rightFunction}.
   */
  public abstract <C> C map(Function<A, C> leftFunction, Function<B, C> rightFunction);

  @Override
  public abstract int hashCode();

  @Override
  public abstract boolean equals(Object other);

  @Override
  public abstract String toString();

  private static class LeftEither<A, B> extends Either<A, B> {
    private final A a;

    private LeftEither(A a) {
      this.a = a;
    }

    @Override
    public void consume(Consumer<A> leftConsumer, Consumer<B> rightConsumer) {
      leftConsumer.accept(a);
    }

    @Override
    public <C> C map(Function<A, C> leftFunction, Function<B, C> rightFunction) {
      return leftFunction.apply(a);
    }

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

    @Override
    public boolean equals(Object other) {
      if (!(other instanceof LeftEither)) {
        return false;
      }
      return Objects.equals(this.a, ((LeftEither) other).a);
    }

    @Override
    public String toString() {
      return "left injection of " + a;
    }
  }

  private static class RightEither<A, B> extends Either<A, B> {
    private final B b;

    private RightEither(B b) {
      this.b = b;
    }

    @Override
    public void consume(Consumer<A> leftConsumer, Consumer<B> rightConsumer) {
      rightConsumer.accept(b);
    }

    @Override
    public <C> C map(Function<A, C> leftFunction, Function<B, C> rightFunction) {
      return rightFunction.apply(b);
    }

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

    @Override
    public boolean equals(Object other) {
      if (!(other instanceof RightEither)) {
        return false;
      }
      return Objects.equals(this.b, ((RightEither) other).b);
    }

    @Override
    public String toString() {
      return "right injection of " + b;
    }
  }
}
