// 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.packages;

import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Parts of an {@link EnvironmentGroup} that are needed for analysis. Since {@link EnvironmentGroup}
 * keeps a reference to a {@link Package} object, it is too heavyweight to store in analysis.
 *
 * <p>Constructor should only be called by {@link EnvironmentGroup}, and this object must never be
 * accessed externally until after {@link EnvironmentGroup#processMemberEnvironments} is called. The
 * mutability of fulfillersMap means that we must take care to wait until it is set before doing
 * anything with this class.
 */
@AutoCodec
public class EnvironmentLabels {
  final Label label;
  final ImmutableSet<Label> environments;
  final ImmutableSet<Label> defaults;
  /**
   * Maps a member environment to the set of environments that directly fulfill it. Note that we
   * can't set this map until all Target instances for member environments have been initialized,
   * which occurs after group instantiation (this makes the class mutable).
   */
  private Map<Label, NestedSet<Label>> fulfillersMap = null;

  EnvironmentLabels(Label label, Collection<Label> environments, Collection<Label> defaults) {
    this(label, environments, defaults, null);
  }

  /**
   * Only for use by serialization: the mutable fulfillersMap object is not properly initialized
   * otherwise during deserialization.
   */
  @AutoCodec.VisibleForSerialization
  @AutoCodec.Instantiator
  EnvironmentLabels(
      Label label,
      Collection<Label> environments,
      Collection<Label> defaults,
      Map<Label, NestedSet<Label>> fulfillersMap) {
    this.label = label;
    this.environments = ImmutableSet.copyOf(environments);
    this.defaults = ImmutableSet.copyOf(defaults);
    this.fulfillersMap = fulfillersMap;
  }

  void assertNotInitialized() {
    Preconditions.checkState(fulfillersMap == null, this);
  }

  void checkInitialized() {
    Preconditions.checkNotNull(fulfillersMap, this);
  }

  void setFulfillersMap(Map<Label, NestedSet<Label>> fulfillersMap) {
    Preconditions.checkState(this.fulfillersMap == null, this);
    this.fulfillersMap = Collections.unmodifiableMap(fulfillersMap);
  }

  public Set<Label> getEnvironments() {
    checkInitialized();
    return environments;
  }

  public Set<Label> getDefaults() {
    checkInitialized();
    return defaults;
  }

  /**
   * Determines whether or not an environment is a default. Returns false if the environment doesn't
   * belong to this group.
   */
  public boolean isDefault(Label environment) {
    checkInitialized();
    return defaults.contains(environment);
  }

  /**
   * Returns the set of environments that transitively fulfill the specified environment. The
   * environment must be a valid member of this group.
   *
   * <p>>For example, if the input is <code>":foo"</code> and <code>":bar"</code> fulfills <code>
   * ":foo"</code> and <code>":baz"</code> fulfills <code>":bar"</code>, this returns <code>
   * [":foo", ":bar", ":baz"]</code>.
   *
   * <p>If no environments fulfill the input, returns an empty set.
   */
  public NestedSet<Label> getFulfillers(Label environment) {
    checkInitialized();
    return fulfillersMap.get(environment);
  }

  public Label getLabel() {
    checkInitialized();
    return label;
  }

  @Override
  public String toString() {
    return MoreObjects.toStringHelper(this)
        .add("label", label)
        .add("sizes", environments.size() + ", " + defaults.size() + ", " + fulfillersMap.size())
        .add("environments", environments)
        .add("defaults", defaults)
        .add("fulfillersMap", fulfillersMap)
        .toString();
  }

  @Override
  public int hashCode() {
    checkInitialized();
    return Objects.hash(label, environments, defaults, fulfillersMap.keySet());
  }

  /**
   * Compares {@code map1} and {@code map2} using deep equality for their values. Should be feasible
   * because comparison will usually only happen between == objects, so this is hit rarely. If
   * objects are equal, but have been deserialized separately so not ==, this should still be ok
   * because these nested sets are not particularly big, and there are very few EnvironmentGroups
   * (and therefore EnvironmentLabels) in any given build.
   *
   * <p>This will have to be revisited if it turns out to be noticeably expensive. It should be
   * sound to not compare the values of the fulfillerMaps at all, since they are determined from the
   * package each EnvironmentLabel is associated with, and so as long as EnvironmentLabels from
   * different source states but the same package are not compared, the values shouldn't be
   * necessary.
   */
  private static boolean fulfillerMapsEqual(
      Map<Label, NestedSet<Label>> map1, Map<Label, NestedSet<Label>> map2) {
    if (map1 == map2) {
      return true;
    }
    if (map1.size() != map2.size()) {
      return false;
    }
    for (Map.Entry<Label, NestedSet<Label>> entry : map1.entrySet()) {
      NestedSet<Label> secondValue = map2.get(entry.getKey());
      // Do shallowEquals check first for speed.
      if (secondValue == null
          || (!entry.getValue().shallowEquals(secondValue)
              && !entry.getValue().toList().equals(secondValue.toList()))) {
        return false;
      }
    }
    return true;
  }

  @Override
  public boolean equals(Object o) {
    checkInitialized();
    if (this == o) {
      return true;
    }
    if (o == null || getClass() != o.getClass()) {
      return false;
    }
    EnvironmentLabels that = (EnvironmentLabels) o;
    that.checkInitialized();
    return label.equals(that.label)
        && environments.equals(that.environments)
        && defaults.equals(that.defaults)
        && fulfillerMapsEqual(this.fulfillersMap, that.fulfillersMap);
  }
}
