// Copyright 2015 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.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
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.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.lib.pkgcache.PackageManager;
import com.google.devtools.build.lib.pkgcache.TestFilter;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec;
import com.google.devtools.build.lib.skyframe.serialization.autocodec.AutoCodec.VisibleForSerialization;
import com.google.devtools.build.skyframe.SkyFunctionName;
import com.google.devtools.build.skyframe.SkyKey;
import com.google.devtools.build.skyframe.SkyValue;
import java.io.Serializable;
import java.util.Collection;
import java.util.Objects;
import javax.annotation.Nullable;

/**
 * A value referring to a computed set of resolved targets. This is used for the results of target
 * pattern parsing.
 */
@Immutable
@ThreadSafe
@VisibleForTesting
@AutoCodec
public final class TargetPatternPhaseValue implements SkyValue {

  private final ImmutableSet<Label> targetLabels;
  @Nullable private final ImmutableSet<Label> testsToRunLabels;
  private final boolean hasError;
  private final boolean hasPostExpansionError;
  private final String workspaceName;

  TargetPatternPhaseValue(
      ImmutableSet<Label> targetLabels,
      ImmutableSet<Label> testsToRunLabels,
      boolean hasError,
      boolean hasPostExpansionError,
      String workspaceName) {
    this.targetLabels = targetLabels;
    this.testsToRunLabels = testsToRunLabels;
    this.hasError = hasError;
    this.hasPostExpansionError = hasPostExpansionError;
    this.workspaceName = workspaceName;
  }

  private static ImmutableSet<Target> getTargetsFromLabels(
      Collection<Label> labels, ExtendedEventHandler eventHandler, PackageManager packageManager)
      throws InterruptedException {
    ImmutableSet.Builder<Target> result = ImmutableSet.builderWithExpectedSize(labels.size());
    for (Label label : labels) {
      try {
        result.add(
            packageManager
                .getPackage(eventHandler, label.getPackageIdentifier())
                .getTarget(label.getName()));
      } catch (NoSuchTargetException | NoSuchPackageException e) {
        throw new IllegalStateException(
            "Failed to get preloaded package from TargetPatternPhaseValue for " + label, e);
      }
    }
    return result.build();
  }

  public ImmutableSet<Target> getTargets(
      ExtendedEventHandler eventHandler, PackageManager packageManager)
      throws InterruptedException {
    return getTargetsFromLabels(targetLabels, eventHandler, packageManager);
  }

  public ImmutableSet<Target> getTestsToRun(
      ExtendedEventHandler eventHandler, PackageManager packageManager)
      throws InterruptedException {
    return getTargetsFromLabels(testsToRunLabels, eventHandler, packageManager);
  }

  public ImmutableSet<Label> getTargetLabels() {
    return targetLabels;
  }

  @Nullable
  public ImmutableSet<Label> getTestsToRunLabels() {
    return testsToRunLabels;
  }

  public boolean hasError() {
    return hasError;
  }

  public boolean hasPostExpansionError() {
    return hasPostExpansionError;
  }

  public String getWorkspaceName() {
    return workspaceName;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof TargetPatternPhaseValue)) {
      return false;
    }
    TargetPatternPhaseValue that = (TargetPatternPhaseValue) obj;
    return Objects.equals(this.targetLabels, that.targetLabels)
        && Objects.equals(this.testsToRunLabels, that.testsToRunLabels)
        && Objects.equals(this.workspaceName, that.workspaceName)
        && this.hasError == that.hasError
        && this.hasPostExpansionError == that.hasPostExpansionError;
  }

  @Override
  public int hashCode() {
    return Objects.hash(
        this.targetLabels,
        this.testsToRunLabels,
        this.workspaceName,
        this.hasError,
        this.hasPostExpansionError);
  }

  /** Create a target pattern phase value key. */
  @ThreadSafe
  public static SkyKey key(
      ImmutableList<String> targetPatterns,
      String offset,
      boolean compileOneDependency,
      boolean buildTestsOnly,
      boolean determineTests,
      ImmutableList<String> buildTargetFilter,
      boolean buildManualTests,
      boolean expandTestSuites,
      @Nullable TestFilter testFilter) {
    return new TargetPatternPhaseKey(
        targetPatterns,
        offset,
        compileOneDependency,
        buildTestsOnly,
        determineTests,
        buildTargetFilter,
        buildManualTests,
        expandTestSuites,
        testFilter);
  }

  /** The configuration needed to run the target pattern evaluation phase. */
  @ThreadSafe
  @VisibleForSerialization
  @AutoCodec
  public static final class TargetPatternPhaseKey implements SkyKey, Serializable {
    private final ImmutableList<String> targetPatterns;
    private final String offset;
    private final boolean compileOneDependency;
    private final boolean buildTestsOnly;
    private final boolean determineTests;
    private final ImmutableList<String> buildTargetFilter;
    private final boolean buildManualTests;
    private final boolean expandTestSuites;
    @Nullable private final TestFilter testFilter;

    TargetPatternPhaseKey(
        ImmutableList<String> targetPatterns,
        String offset,
        boolean compileOneDependency,
        boolean buildTestsOnly,
        boolean determineTests,
        ImmutableList<String> buildTargetFilter,
        boolean buildManualTests,
        boolean expandTestSuites,
        @Nullable TestFilter testFilter) {
      this.targetPatterns = Preconditions.checkNotNull(targetPatterns);
      this.offset = Preconditions.checkNotNull(offset);
      this.compileOneDependency = compileOneDependency;
      this.buildTestsOnly = buildTestsOnly;
      this.determineTests = determineTests;
      this.buildTargetFilter = Preconditions.checkNotNull(buildTargetFilter);
      this.buildManualTests = buildManualTests;
      this.expandTestSuites = expandTestSuites;
      this.testFilter = testFilter;
      if (buildTestsOnly || determineTests) {
        Preconditions.checkNotNull(testFilter);
      }
    }

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

    public ImmutableList<String> getTargetPatterns() {
      return targetPatterns;
    }

    public String getOffset() {
      return offset;
    }

    public boolean getCompileOneDependency() {
      return compileOneDependency;
    }

    public boolean getBuildTestsOnly() {
      return buildTestsOnly;
    }

    public boolean getDetermineTests() {
      return determineTests;
    }

    public ImmutableList<String> getBuildTargetFilter() {
      return buildTargetFilter;
    }

    public boolean getBuildManualTests() {
      return buildManualTests;
    }

    public TestFilter getTestFilter() {
      return testFilter;
    }

    public boolean isExpandTestSuites() {
      return expandTestSuites;
    }

    @Override
    public String toString() {
      StringBuilder result = new StringBuilder();
      result.append(targetPatterns);
      if (!offset.isEmpty()) {
        result.append(" OFFSET=").append(offset);
      }
      result.append(compileOneDependency ? " COMPILE_ONE_DEPENDENCY" : "");
      result.append(buildTestsOnly ? " BUILD_TESTS_ONLY" : "");
      result.append(determineTests ? " DETERMINE_TESTS" : "");
      result.append(expandTestSuites ? " EXPAND_TEST_SUITES" : "");
      result.append(testFilter != null ? " " + testFilter : "");
      return result.toString();
    }

    @Override
    public int hashCode() {
      return Objects.hash(
          targetPatterns,
          offset,
          compileOneDependency,
          buildTestsOnly,
          determineTests,
          buildManualTests,
          expandTestSuites,
          testFilter);
    }

    @Override
    public boolean equals(Object obj) {
      if (this == obj) {
        return true;
      }
      if (!(obj instanceof TargetPatternPhaseKey)) {
        return false;
      }
      TargetPatternPhaseKey other = (TargetPatternPhaseKey) obj;
      return other.targetPatterns.equals(this.targetPatterns)
          && other.offset.equals(this.offset)
          && other.compileOneDependency == compileOneDependency
          && other.buildTestsOnly == buildTestsOnly
          && other.determineTests == determineTests
          && other.buildTargetFilter.equals(buildTargetFilter)
          && other.buildManualTests == buildManualTests
          && other.expandTestSuites == expandTestSuites
          && Objects.equals(other.testFilter, testFilter);
    }
  }
}
