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

import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.TestSize;
import com.google.devtools.build.lib.packages.TestTargetUtils;
import com.google.devtools.build.lib.packages.TestTimeout;

import java.util.List;
import java.util.Objects;
import java.util.Set;

import javax.annotation.Nullable;

/**
 * Predicate that implements test filtering using the command-line options in {@link LoadingOptions}.
 * Implements {@link #hashCode} and {@link #equals} so it can be used as a Skyframe key.
 */
public final class TestFilter implements Predicate<Target> {
  /**
   * Convert the options into a test filter.
   */
  public static TestFilter forOptions(LoadingOptions options, EventHandler eventHandler,
      Set<String> ruleNames) {
    Predicate<Target> testFilter = Predicates.alwaysTrue();
    if (!options.testSizeFilterSet.isEmpty()) {
      testFilter = Predicates.and(testFilter,
          TestTargetUtils.testSizeFilter(options.testSizeFilterSet));
    }
    if (!options.testTimeoutFilterSet.isEmpty()) {
      testFilter = Predicates.and(testFilter,
          TestTargetUtils.testTimeoutFilter(options.testTimeoutFilterSet));
    }
    if (!options.testTagFilterList.isEmpty()) {
      testFilter = Predicates.and(testFilter,
          TestTargetUtils.tagFilter(options.testTagFilterList));
    }
    if (!options.testLangFilterList.isEmpty()) {
      testFilter = Predicates.and(testFilter,
          TestTargetUtils.testLangFilter(options.testLangFilterList, eventHandler, ruleNames));
    }
    return new TestFilter(options.testSizeFilterSet, options.testTimeoutFilterSet,
        options.testTagFilterList, options.testLangFilterList, testFilter);
  }

  private final Set<TestSize> testSizeFilterSet;
  private final Set<TestTimeout> testTimeoutFilterSet;
  private final List<String> testTagFilterList;
  private final List<String> testLangFilterList;
  private final Predicate<Target> impl;

  private TestFilter(Set<TestSize> testSizeFilterSet, Set<TestTimeout> testTimeoutFilterSet,
      List<String> testTagFilterList, List<String> testLangFilterList, Predicate<Target> impl) {
    this.testSizeFilterSet = testSizeFilterSet;
    this.testTimeoutFilterSet = testTimeoutFilterSet;
    this.testTagFilterList = testTagFilterList;
    this.testLangFilterList = testLangFilterList;
    this.impl = impl;
  }

  @Override
  public boolean apply(@Nullable Target input) {
    return impl.apply(input);
  }

  @Override
  public int hashCode() {
    return Objects.hash(testSizeFilterSet, testTimeoutFilterSet, testTagFilterList,
        testLangFilterList);
  }

  @Override
  public boolean equals(Object o) {
    if (o == this) {
      return true;
    }
    if (!(o instanceof TestFilter)) {
      return false;
    }
    TestFilter f = (TestFilter) o;
    return f.testSizeFilterSet.equals(testSizeFilterSet)
        && f.testTimeoutFilterSet.equals(testTimeoutFilterSet)
        && f.testTagFilterList.equals(testTagFilterList)
        && f.testLangFilterList.equals(testLangFilterList);
  }
}
