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

import com.google.common.base.MoreObjects;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.devtools.build.lib.analysis.TargetAndConfiguration;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationCollection;
import com.google.devtools.build.lib.analysis.config.BuildConfigurationValue;
import com.google.devtools.build.lib.analysis.config.BuildOptions;
import com.google.devtools.build.lib.analysis.config.ConfigurationResolver.TopLevelTargetsAndConfigsResult;
import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.concurrent.ThreadSafety.Immutable;
import com.google.devtools.build.lib.concurrent.ThreadSafety.ThreadSafe;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.ExtendedEventHandler;
import com.google.devtools.build.lib.packages.NoSuchPackageException;
import com.google.devtools.build.lib.packages.NoSuchTargetException;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * A value referring to a set of build configuration keys in order to reconstruct the
 * legacy {@link BuildConfigurationCollection} as well as a set of top level configured target keys
 * that are subsequently requested to trigger the analysis phase.
 *
 * <p>The public interface returns {@link BuildConfigurationCollection} and {@link
 * TargetAndConfiguration} even though these are not internally stored - the construction of these
 * objects requires additional Skyframe calls. The intention is that these are temporary until a
 * larger fraction of the code has been ported to Skyframe, at which point we'll use the internal
 * representation.
 */
@Immutable
@ThreadSafe
public final class PrepareAnalysisPhaseValue implements SkyValue {
  private final BuildConfigurationKey hostConfigurationKey;
  private final ImmutableList<BuildConfigurationKey> targetConfigurationKeys;
  private final ImmutableList<ConfiguredTargetKey> topLevelCtKeys;

  PrepareAnalysisPhaseValue(
      BuildConfigurationKey hostConfigurationKey,
      ImmutableList<BuildConfigurationKey> targetConfigurationKeys,
      ImmutableList<ConfiguredTargetKey> topLevelCtKeys) {
    this.hostConfigurationKey = Preconditions.checkNotNull(hostConfigurationKey);
    this.targetConfigurationKeys = Preconditions.checkNotNull(targetConfigurationKeys);
    this.topLevelCtKeys = Preconditions.checkNotNull(topLevelCtKeys);
  }

  /**
   * Returns the legacy {@link BuildConfigurationCollection}. Note that this performs additional
   * Skyframe calls, which may be expensive.
   */
  public BuildConfigurationCollection getConfigurations(
      ExtendedEventHandler eventHandler, SkyframeExecutor skyframeExecutor)
          throws InvalidConfigurationException {
    BuildConfigurationValue hostConfiguration =
        skyframeExecutor.getConfiguration(eventHandler, hostConfigurationKey);
    ImmutableList<BuildConfigurationValue> targetConfigurations =
        ImmutableList.copyOf(
            skyframeExecutor.getConfigurations(eventHandler, targetConfigurationKeys).values());
    return new BuildConfigurationCollection(targetConfigurations, hostConfiguration);
  }

  /**
   * Returns the intended top-level targets and configurations for the build. Note that this
   * performs additional Skyframe calls for the involved configurations and targets, which may be
   * expensive.
   *
   * <p>Skips targets that have errors and registers the errors to be reported later as part of
   * {@link com.google.devtools.build.lib.analysis.AnalysisResult} error resolution.
   */
  public TopLevelTargetsAndConfigsResult getTopLevelCts(
      ExtendedEventHandler eventHandler, SkyframeExecutor skyframeExecutor) {
    List<TargetAndConfiguration> result = new ArrayList<>();
    Map<BuildConfigurationKey, BuildConfigurationValue> configs =
        skyframeExecutor.getConfigurations(
            eventHandler,
            topLevelCtKeys.stream()
                .map(ConfiguredTargetKey::getConfigurationKey)
                .filter(Predicates.notNull())
                .collect(Collectors.toSet()));

    // TODO(ulfjack): This performs one Skyframe call per top-level target. This is not a
    // regression, but we should fix it nevertheless, either by doing a bulk lookup call or by
    // migrating the consumers of these to Skyframe so they can directly request the values.
    boolean hasError = false;
    for (ConfiguredTargetKey key : topLevelCtKeys) {
      Target target;
      try {
        target = skyframeExecutor.getPackageManager().getTarget(eventHandler, key.getLabel());
      } catch (NoSuchPackageException | NoSuchTargetException | InterruptedException e) {
        eventHandler.handle(
            Event.error("Failed to get package from TargetPatternPhaseValue: " + e.getMessage()));
        hasError = true;
        continue;
      }
      BuildConfigurationValue config =
          key.getConfigurationKey() == null ? null : configs.get(key.getConfigurationKey());
      result.add(new TargetAndConfiguration(target, config));
    }
    return new TopLevelTargetsAndConfigsResult(result, hasError);
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof PrepareAnalysisPhaseValue)) {
      return false;
    }
    PrepareAnalysisPhaseValue that = (PrepareAnalysisPhaseValue) obj;
    return this.hostConfigurationKey.equals(that.hostConfigurationKey)
        && this.targetConfigurationKeys.equals(that.targetConfigurationKeys)
        && this.topLevelCtKeys.equals(that.topLevelCtKeys);
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        this.hostConfigurationKey,
        this.targetConfigurationKeys,
        this.topLevelCtKeys);
  }

  /** Create a prepare analysis phase key. */
  @ThreadSafe
  public static SkyKey key(
      BuildOptions options,
      Set<String> multiCpu,
      Collection<Label> labels) {
    return new PrepareAnalysisPhaseKey(options, multiCpu, labels);
  }

  /** The configuration needed to prepare the analysis phase. */
  @ThreadSafe
  @Immutable
  static final class PrepareAnalysisPhaseKey implements SkyKey {
    private final BuildOptions options;
    private final ImmutableSortedSet<String> multiCpu;
    private final ImmutableSet<Label> labels;

    private PrepareAnalysisPhaseKey(
        BuildOptions options,
        Set<String> multiCpu,
        Collection<Label> labels) {
      this.options = Preconditions.checkNotNull(options);
      this.multiCpu = ImmutableSortedSet.copyOf(multiCpu);
      this.labels = ImmutableSet.copyOf(labels);
    }

    @Override
    public SkyFunctionName functionName() {
      return SkyFunctions.PREPARE_ANALYSIS_PHASE;
    }

    public BuildOptions getOptions() {
      return options;
    }

    public ImmutableSortedSet<String> getMultiCpu() {
      return multiCpu;
    }

    public ImmutableSet<Label> getLabels() {
      return labels;
    }

    @Override
    public String toString() {
      return MoreObjects.toStringHelper(PrepareAnalysisPhaseKey.class)
          .add("optionsDiff", options)
          .add("multiCpu", multiCpu)
          .add("labels", labels)
          .toString();
    }

    @Override
    public int hashCode() {
      return Objects.hash(options, multiCpu, labels);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!(obj instanceof PrepareAnalysisPhaseKey)) {
        return false;
      }
      PrepareAnalysisPhaseKey other = (PrepareAnalysisPhaseKey) obj;
      return other.options.equals(this.options)
          && other.multiCpu.equals(multiCpu)
          && other.labels.equals(labels);
    }
  }
}
