// Copyright 2023 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.producers;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.packages.Globber.Operation;
import com.google.devtools.build.lib.packages.producers.GlobComputationProducer.GlobDetail;
import com.google.devtools.build.lib.skyframe.PackageLookupValue;
import com.google.devtools.build.lib.util.Pair;
import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.state.StateMachine;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.Nullable;

/**
 * Handles package (sub-)directory entry which is also a directory and matches part or all of the
 * glob pattern fragments.
 *
 * <p>Created by {@link PatternWithWildcardProducer} or {@link PatternWithoutWildcardProducer} after
 * they confirm that {@linkplain #direntPath the directory dirent} matches part or all of the glob
 * pattern fragments. File dirents are handled inline within the two upstream producers.
 *
 * <p>Checks whether {@link #direntPath} is a qualified glob matching result, and add to result if
 * so. Before creating the next {@link FragmentProducer} also checks whether (1) there are pattern
 * fragment(s) left to match and (2) subpackage crossing exists .
 */
final class DirectoryDirentProducer implements StateMachine, Consumer<SkyValue> {

  // -------------------- Input --------------------
  private final GlobDetail globDetail;

  /** The {@link PathFragment} of the dirent containing the package fragments. */
  private final PathFragment direntPath;

  private final int fragmentIndex;

  // -------------------- Internal State --------------------
  private PackageLookupValue packageLookupValue = null;
  @Nullable private final Set<Pair<PathFragment, Integer>> visitedGlobSubTasks;

  // -------------------- Output --------------------
  private final FragmentProducer.ResultSink resultSink;

  DirectoryDirentProducer(
      GlobDetail globDetail,
      PathFragment direntPath,
      int fragmentIndex,
      FragmentProducer.ResultSink resultSink,
      @Nullable Set<Pair<PathFragment, Integer>> visitedGlobSubTasks) {
    // Upstream logic should already have appended some dirent to the package fragment when
    // constructing this `direntPath`.
    Preconditions.checkArgument(
        !direntPath.equals(globDetail.packageIdentifier().getPackageFragment()));
    this.direntPath = direntPath;
    this.globDetail = globDetail;
    this.fragmentIndex = fragmentIndex;
    this.resultSink = resultSink;
    this.visitedGlobSubTasks = visitedGlobSubTasks;
  }

  @Override
  public StateMachine step(Tasks tasks) {
    // Check whether the next directory path matches any `IgnoredPackagePrefix`.
    for (PathFragment ignoredPrefix : globDetail.ignoredPackagePrefixesPatterns()) {
      if (direntPath.startsWith(ignoredPrefix)) {
        return DONE;
      }
    }

    tasks.lookUp(
        PackageLookupValue.key(
            PackageIdentifier.create(globDetail.packageIdentifier().getRepository(), direntPath)),
        (Consumer<SkyValue>) this);
    return this::checkSubpackageExistence;
  }

  @Override
  public void accept(SkyValue skyValue) {
    packageLookupValue = (PackageLookupValue) skyValue;
  }

  private StateMachine checkSubpackageExistence(Tasks tasks) {
    Preconditions.checkNotNull(packageLookupValue);
    if (packageLookupValue
        instanceof PackageLookupValue.IncorrectRepositoryReferencePackageLookupValue) {
      // Cross repository boundary, so glob expansion should not descend into that subdir.
      return DONE;
    }

    if (packageLookupValue.packageExists()) {
      // Cross the package boundary. The subdir contains a BUILD file and thus defines another
      // package, so glob expansion should not descend into that subdir.
      if (globDetail.globOperation().equals(Operation.SUBPACKAGES)) {
        // If this is a subpackages() call, we need to check whether this subpackage is a glob
        // matching before returning.
        if (shouldAddResult(/* isSubpackage= */ true)) {
          resultSink.acceptPathFragmentWithPackageFragment(direntPath);
        }
      }
      return DONE;
    }

    return addResultsOrCreateNextFragmentProducer(tasks);
  }

  private StateMachine addResultsOrCreateNextFragmentProducer(Tasks tasks) {
    // Even for directory dirent, we need to check whether this path is a matching result.
    if (shouldAddResult(/* isSubpackage= */ false)) {
      resultSink.acceptPathFragmentWithPackageFragment(direntPath);
    }

    int nextFragmentIndex =
        globDetail.patternFragments().get(fragmentIndex).equals("**")
            ? fragmentIndex
            : fragmentIndex + 1;
    if (nextFragmentIndex == globDetail.patternFragments().size()) {
      // When the last glob pattern is not double star, we have already processed all pattern
      // fragments, so execution enters this block and immediately returns.
      return DONE;
    }

    if (visitedGlobSubTasks == null
        || visitedGlobSubTasks.add(Pair.of(direntPath, nextFragmentIndex))) {
      // Create the next unvisited `FragmentProducer` if it has not been processed.
      tasks.enqueue(
          new FragmentProducer(
              globDetail, direntPath, nextFragmentIndex, visitedGlobSubTasks, resultSink));
    }
    return DONE;
  }

  /** Returns {@code true} if {@code path} can be added as a glob matching result. */
  private boolean shouldAddResult(boolean isSubpackage) {
    switch (globDetail.globOperation()) {
      case FILES:
        // The dirent is always a directory, so it can never match FILE operation.
        return false;
      case SUBPACKAGES:
        return isSubpackage
            && allRemainPatternFragmentsDoubleStar(globDetail.patternFragments(), fragmentIndex);
      case FILES_AND_DIRS:
        return fragmentIndex == globDetail.patternFragments().size() - 1 && !isSubpackage;
    }
    throw new IllegalStateException(
        "Unexpected globber globberOperation = [" + globDetail.globOperation() + "]");
  }

  private static boolean allRemainPatternFragmentsDoubleStar(
      ImmutableList<String> patternFragments, int index) {
    if (index == patternFragments.size() - 1) {
      // Already covered all pattern fragments at this point, so we don't need to check additional
      // pattern fragments.
      return true;
    }
    return patternFragments.subList(index + 1, patternFragments.size()).stream()
        .allMatch("**"::equals);
  }
}
