// 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 Iterable<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);
  }
}
