// Copyright 2014 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.cmdline;

import static com.google.common.util.concurrent.Futures.immediateCancelledFuture;
import static com.google.common.util.concurrent.Futures.immediateFailedFuture;
import static com.google.common.util.concurrent.Futures.immediateVoidFuture;

import com.google.common.collect.ImmutableSet;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.devtools.build.lib.io.InconsistentFilesystemException;
import com.google.devtools.build.lib.io.ProcessPackageDirectoryException;
import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Collection;

/**
 * A callback that is used during the process of converting target patterns (such as <code>//foo:all
 * </code>) into one or more lists of targets (such as <code>//foo:foo,
 * //foo:bar</code>). During a call to {@link TargetPattern#eval}, the {@link TargetPattern} makes
 * calls to this interface to implement the target pattern semantics. The generic type {@code T} is
 * only for compile-time type safety; there are no requirements to the actual type.
 */
public abstract class TargetPatternResolver<T> {

  /** Reports the given warning. */
  public abstract void warn(String msg);

  /**
   * Returns a single target corresponding to the given label, or null. This method may only throw
   * an exception if the current thread was interrupted.
   */
  public abstract T getTargetOrNull(Label label)
      throws InterruptedException, InconsistentFilesystemException;

  /** Returns a single target corresponding to the given label, or an empty or failed result. */
  public abstract ResolvedTargets<T> getExplicitTarget(Label label)
      throws TargetParsingException, InterruptedException;

  /**
   * Returns the set containing the targets found in the given package. The specified directory is
   * not necessarily a valid package name. If {@code rulesOnly} is true, then this method should
   * only return rules in the given package.
   *
   * @param originalPattern the original target pattern for error reporting purposes
   * @param packageIdentifier the identifier of the package
   * @param rulesOnly whether to return rules only
   */
  public abstract Collection<T> getTargetsInPackage(
      String originalPattern, PackageIdentifier packageIdentifier, boolean rulesOnly)
      throws TargetParsingException, InterruptedException;

  /**
   * Computes the set containing the targets found below the given {@code directory}, passing it in
   * batches to {@code callback}. Conceptually, this method should look for all packages that start
   * with the {@code directory} (as a proper prefix directory, i.e., "foo/ba" is not a proper prefix
   * of "foo/bar/"), and then collect all targets in each such package (subject to {@code
   * rulesOnly}) as if calling {@link #getTargetsInPackage}. The specified directory is not
   * necessarily a valid package name.
   *
   * <p>Note that the {@code directory} can be empty, which corresponds to the "//..." pattern.
   * Implementations may choose not to support this case and throw an {@link
   * IllegalArgumentException} exception instead, or may restrict the set of directories that are
   * considered by default.
   *
   * <p>If the {@code directory} points to a package, then that package should also be part of the
   * result.
   *
   * @param originalPattern the original target pattern for error reporting purposes
   * @param directory the directory in which to look for packages
   * @param rulesOnly whether to return rules only
   * @param forbiddenSubdirectories a set of transitive subdirectories beneath {@code directory} to
   *     ignore
   * @param excludedSubdirectories another set of transitive subdirectories beneath {@code
   *     directory} to ignore
   * @param callback the callback to receive the result, possibly in multiple batches.
   * @param exceptionClass The class type of the parameterized exception.
   * @throws TargetParsingException under implementation-specific failure conditions
   * @throws ProcessPackageDirectoryException only when called from within Skyframe and an
   *     inconsistent filesystem state is observed
   */
  public abstract <E extends Exception & QueryExceptionMarkerInterface>
      void findTargetsBeneathDirectory(
          RepositoryName repository,
          String originalPattern,
          String directory,
          boolean rulesOnly,
          ImmutableSet<PathFragment> forbiddenSubdirectories,
          ImmutableSet<PathFragment> excludedSubdirectories,
          BatchCallback<T, E> callback,
          Class<E> exceptionClass)
          throws TargetParsingException, E, InterruptedException, ProcessPackageDirectoryException;

  /**
   * Async version of {@link #findTargetsBeneathDirectory}. Never call this from within Skyframe
   * evaluation.
   *
   * <p>Default implementation is synchronous.
   */
  public <E extends Exception & QueryExceptionMarkerInterface>
      ListenableFuture<Void> findTargetsBeneathDirectoryAsync(
          RepositoryName repository,
          String originalPattern,
          String directory,
          boolean rulesOnly,
          ImmutableSet<PathFragment> forbiddenSubdirectories,
          ImmutableSet<PathFragment> excludedSubdirectories,
          BatchCallback<T, E> callback,
          Class<E> exceptionClass,
          ListeningExecutorService executor) {
    try {
      findTargetsBeneathDirectory(
          repository,
          originalPattern,
          directory,
          rulesOnly,
          forbiddenSubdirectories,
          excludedSubdirectories,
          callback,
          exceptionClass);
      return immediateVoidFuture();
    } catch (TargetParsingException e) {
      return immediateFailedFuture(e);
    } catch (InterruptedException e) {
      return immediateCancelledFuture();
    } catch (ProcessPackageDirectoryException e) {
      throw new IllegalStateException(
          "Async find targets beneath directory isn't called from within Skyframe: traversing "
              + directory
              + " for "
              + originalPattern,
          e);
    } catch (Exception e) {
      if (exceptionClass.isInstance(e)) {
        return immediateFailedFuture(e);
      }
      throw new IllegalStateException(e);
    }
  }

  /**
   * Returns true, if and only if the given package identifier corresponds to a package, i.e., a
   * file with the name {@code packageName/BUILD} exists in the appropriate repository.
   */
  public abstract boolean isPackage(PackageIdentifier packageIdentifier)
      throws InterruptedException, InconsistentFilesystemException;

  /** Returns the target kind of the given target, for example {@code cc_library rule}. */
  public abstract String getTargetKind(T target);
}
