// 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.devtools.build.lib.actions.FileValue;
import com.google.devtools.build.lib.io.InconsistentFilesystemException;
import com.google.devtools.build.skyframe.SkyValue;
import com.google.devtools.build.skyframe.state.StateMachine;
import java.util.function.Consumer;

/**
 * Looks up {@link FileValue} for a {@link FileValue.Key} which is guaranteed to be a symlink.
 *
 * <p>Used when {@link PatternWithWildcardProducer} handles {@link
 * com.google.devtools.build.lib.skyframe.DirectoryListingValue}. For any {@link
 * com.google.devtools.build.lib.vfs.Dirent} which is a {@code SYMLINK}, computes its {@link
 * FileValue} to know the target path.
 *
 * <p>When handling each {@code DirectoryListingValue}, multiple {@link SymlinkProducer}s can be
 * created so that {@link com.google.devtools.build.skyframe.state.Driver} is able to query the
 * symlink dirents in a batch. All symlink dirents {@link FileValue} will be collected in an array
 * list and the runAfter method should be executed only once. So {@link SymlinkProducer} does not
 * expect any runAfter {@link StateMachine} to be passed in.
 *
 * <p>If the {@link FileValue} from skyframe shows that this is not a symlink, accepts an {@link
 * InconsistentFilesystemException} which will be bubbled up.
 */
final class SymlinkProducer implements StateMachine, Consumer<SkyValue> {

  interface ResultSink {
    void acceptSymlinkFileValue(FileValue symlinkValue, FileValue.Key symlinkKey);

    void acceptInconsistentFilesystemException(InconsistentFilesystemException exception);
  }

  // -------------------- Input --------------------
  private final FileValue.Key symlinkKey;

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

  SymlinkProducer(FileValue.Key symlinkKey, ResultSink resultSink) {
    this.symlinkKey = symlinkKey;
    this.resultSink = resultSink;
  }

  @Override
  public StateMachine step(Tasks tasks) {
    tasks.lookUp(symlinkKey, (Consumer<SkyValue>) this);
    return DONE;
  }

  @Override
  public void accept(SkyValue skyValue) {
    Preconditions.checkState(skyValue instanceof FileValue);
    FileValue symlinkValue = (FileValue) skyValue;

    if (!symlinkValue.isSymlink()) {
      resultSink.acceptInconsistentFilesystemException(
          new InconsistentFilesystemException(
              "readdir and stat disagree about whether "
                  + symlinkKey.argument().asPath()
                  + " is a symlink."));
      return;
    }

    resultSink.acceptSymlinkFileValue(symlinkValue, symlinkKey);
  }
}
