// Copyright 2014 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
package com.google.devtools.build.skyframe;

import com.google.common.base.Preconditions;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.events.ExtendedEventHandler.Postable;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * Encapsulation of data stored by {@link NodeEntry} when the value has finished building.
 *
 * <p>This is intended only for use in alternative {@code MemoizingEvaluator} implementations.
 */
public abstract class ValueWithMetadata implements SkyValue {
  protected final SkyValue value;

  private static final NestedSet<TaggedEvents> NO_EVENTS =
      NestedSetBuilder.<TaggedEvents>emptySet(Order.STABLE_ORDER);

  private static final NestedSet<Postable> NO_POSTS =
      NestedSetBuilder.<Postable>emptySet(Order.STABLE_ORDER);

  public ValueWithMetadata(SkyValue value) {
    this.value = value;
  }

  /**
   * Builds a value entry value that has an error (and no value value).
   *
   * <p>This is intended only for use in alternative {@code MemoizingEvaluator} implementations.
   */
  public static ValueWithMetadata error(
      ErrorInfo errorInfo,
      NestedSet<TaggedEvents> transitiveEvents,
      NestedSet<Postable> transitivePostables) {
    return new ErrorInfoValue(errorInfo, null, transitiveEvents, transitivePostables);
  }

  /**
   * Builds a value entry value that has a value value, and possibly an error (constructed from its
   * children's errors).
   *
   * <p>This is public only for use in alternative {@code MemoizingEvaluator} implementations.
   */
  public static SkyValue normal(
      @Nullable SkyValue value,
      @Nullable ErrorInfo errorInfo,
      NestedSet<TaggedEvents> transitiveEvents,
      NestedSet<Postable> transitivePostables) {
    Preconditions.checkState(value != null || errorInfo != null,
        "Value and error cannot both be null");
    if (errorInfo == null) {
      return (transitiveEvents.isEmpty() && transitivePostables.isEmpty())
          ? value
          : ValueWithEvents.createValueWithEvents(value, transitiveEvents, transitivePostables);
    }
    return new ErrorInfoValue(errorInfo, value, transitiveEvents, transitivePostables);
  }

  @Nullable SkyValue getValue() {
    return value;
  }

  @Nullable
  abstract ErrorInfo getErrorInfo();

  public abstract NestedSet<TaggedEvents> getTransitiveEvents();

  public abstract NestedSet<Postable> getTransitivePostables();

  /** Implementation of {@link ValueWithMetadata} for the value case. */
  public static class ValueWithEvents extends ValueWithMetadata {

    private final NestedSet<TaggedEvents> transitiveEvents;
    private final NestedSet<Postable> transitivePostables;

    private ValueWithEvents(
        SkyValue value,
        NestedSet<TaggedEvents> transitiveEvents,
        NestedSet<Postable> transitivePostables) {
      super(Preconditions.checkNotNull(value));
      this.transitiveEvents = Preconditions.checkNotNull(transitiveEvents);
      this.transitivePostables = Preconditions.checkNotNull(transitivePostables);
    }

    public static ValueWithEvents createValueWithEvents(
        SkyValue value,
        NestedSet<TaggedEvents> transitiveEvents,
        NestedSet<Postable> transitivePostables) {
      if (value instanceof NotComparableSkyValue) {
        return new NotComparableValueWithEvents(value, transitiveEvents, transitivePostables);
      } else {
        return new ValueWithEvents(value, transitiveEvents, transitivePostables);
      }
    }

    @Nullable
    @Override
    ErrorInfo getErrorInfo() { return null; }

    @Override
    public NestedSet<TaggedEvents> getTransitiveEvents() { return transitiveEvents; }

    @Override
    public NestedSet<Postable> getTransitivePostables() {
      return transitivePostables;
    }

    /**
     * We override equals so that if the same value is written to a {@link NodeEntry} twice, it can
     * verify that the two values are equal, and avoid incrementing its version.
     */
    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      ValueWithEvents that = (ValueWithEvents) o;

      // Shallow equals is a middle ground between using default equals, which might miss
      // nested sets with the same elements, and deep equality checking, which would be expensive.
      // All three choices are sound, since shallow equals and default equals are more
      // conservative than deep equals. Using shallow equals means that we may unnecessarily
      // consider some values unequal that are actually equal, but this is still a net win over
      // deep equals.
      return value.equals(that.value)
          && transitiveEvents.shallowEquals(that.transitiveEvents)
          && transitivePostables.shallowEquals(that.transitivePostables);
    }

    @Override
    public int hashCode() {
      return 31 * value.hashCode()
          + transitiveEvents.shallowHashCode()
          + 3 * transitivePostables.shallowHashCode();
    }

    @Override
    public String toString() { return value.toString(); }
  }

  private static final class NotComparableValueWithEvents extends ValueWithEvents
          implements NotComparableSkyValue {
    private NotComparableValueWithEvents(
        SkyValue value,
        NestedSet<TaggedEvents> transitiveEvents,
        NestedSet<Postable> transitivePostables) {
      super(value, transitiveEvents, transitivePostables);
    }
  }

  /**
   * Implementation of {@link ValueWithMetadata} for the error case.
   *
   * ErorInfo does not override equals(), so it may as well be marked NotComparableSkyValue.
   */
  private static final class ErrorInfoValue extends ValueWithMetadata
          implements NotComparableSkyValue {

    private final ErrorInfo errorInfo;
    private final NestedSet<TaggedEvents> transitiveEvents;
    private final NestedSet<Postable> transitivePostables;

    public ErrorInfoValue(
        ErrorInfo errorInfo,
        @Nullable SkyValue value,
        NestedSet<TaggedEvents> transitiveEvents,
        NestedSet<Postable> transitivePostables) {
      super(value);
      this.errorInfo = Preconditions.checkNotNull(errorInfo);
      this.transitiveEvents = Preconditions.checkNotNull(transitiveEvents);
      this.transitivePostables = Preconditions.checkNotNull(transitivePostables);
    }

    @Nullable
    @Override
    ErrorInfo getErrorInfo() { return errorInfo; }

    @Override
    public NestedSet<TaggedEvents> getTransitiveEvents() { return transitiveEvents; }

    @Override
    public NestedSet<Postable> getTransitivePostables() {
      return transitivePostables;
    }

    @Override
    public boolean equals(Object o) {
      if (this == o) {
        return true;
      }
      if (o == null || getClass() != o.getClass()) {
        return false;
      }

      ErrorInfoValue that = (ErrorInfoValue) o;

      // Shallow equals is a middle ground between using default equals, which might miss
      // nested sets with the same elements, and deep equality checking, which would be expensive.
      // All three choices are sound, since shallow equals and default equals are more
      // conservative than deep equals. Using shallow equals means that we may unnecessarily
      // consider some values unequal that are actually equal, but this is still a net win over
      // deep equals.
      return Objects.equals(this.value, that.value)
          && Objects.equals(this.errorInfo, that.errorInfo)
          && transitiveEvents.shallowEquals(that.transitiveEvents)
          && transitivePostables.shallowEquals(that.transitivePostables);
    }

    @Override
    public int hashCode() {
      return 31 * Objects.hash(value, errorInfo)
          + transitiveEvents.shallowHashCode()
          + 3 * transitivePostables.shallowHashCode();
    }

    @Override
    public String toString() {
      StringBuilder result = new StringBuilder();
      if (value != null) {
        result.append("Value: ").append(value);
      }
      if (errorInfo != null) {
        if (result.length() > 0) {
          result.append("; ");
        }
        result.append("Error: ").append(errorInfo);
      }
      return result.toString();
    }
  }

  public static SkyValue justValue(SkyValue value) {
    if (value instanceof ValueWithMetadata) {
      return ((ValueWithMetadata) value).getValue();
    }
    return value;
  }

  public static ValueWithMetadata wrapWithMetadata(SkyValue value) {
    if (value instanceof ValueWithMetadata) {
      return (ValueWithMetadata) value;
    }
    return ValueWithEvents.createValueWithEvents(value, NO_EVENTS, NO_POSTS);
  }

  @Nullable
  public static ErrorInfo getMaybeErrorInfo(SkyValue value) {
    if (value.getClass() == ErrorInfoValue.class) {
      return ((ValueWithMetadata) value).getErrorInfo();
    }
    return null;
  }

  static NestedSet<TaggedEvents> getEvents(SkyValue value) {
    if (value instanceof ValueWithMetadata) {
      return ((ValueWithMetadata) value).getTransitiveEvents();
    }
    return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  }

  static NestedSet<Postable> getPosts(SkyValue value) {
    if (value instanceof ValueWithMetadata) {
      return ((ValueWithMetadata) value).getTransitivePostables();
    }
    return NestedSetBuilder.emptySet(Order.STABLE_ORDER);
  }
}
