// 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.collect.ImmutableSet;
import com.google.common.truth.Truth;
import com.google.devtools.build.lib.clock.BlazeClock;
import com.google.devtools.build.lib.events.EventKind;
import com.google.devtools.build.lib.vfs.DigestHashFunction;
import com.google.devtools.build.lib.vfs.Dirent;
import com.google.devtools.build.lib.vfs.FileStatus;
import com.google.devtools.build.lib.vfs.FileSystem;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.Path;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryContentInfo;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.Nullable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** TargetPatternEvaluator tests that require a custom filesystem. */
@RunWith(JUnit4.class)
public class TargetPatternEvaluatorIOTest extends AbstractTargetPatternEvaluatorTest {
  private static class Transformer {
    @SuppressWarnings("unused")
    @Nullable
    public FileStatus stat(FileStatus stat, Path path, boolean followSymlinks) throws IOException {
      return stat;
    }

    @SuppressWarnings("unused")
    @Nullable
    public Collection<Dirent> readdir(Collection<Dirent> readdir, Path path, boolean followSymlinks)
        throws IOException {
      return readdir;
    }
  }

  private Transformer transformer = new Transformer();

  @Override
  protected FileSystem createFileSystem() {
    return new InMemoryFileSystem(DigestHashFunction.SHA256) {
      @Override
      public FileStatus stat(Path path, boolean followSymlinks) throws IOException {
        FileStatus defaultResult = super.stat(path, followSymlinks);
        return transformer.stat(defaultResult, path, followSymlinks);
      }

      @Nullable
      @Override
      public FileStatus statIfFound(Path path, boolean followSymlinks) {
        return statNullable(path, followSymlinks);
      }

      @Nullable
      @Override
      public FileStatus statNullable(Path path, boolean followSymlinks) {
        FileStatus defaultResult = super.statNullable(path, followSymlinks);
        try {
          return transformer.stat(defaultResult, path, followSymlinks);
        } catch (IOException e) {
          return null;
        }
      }

      @Override
      protected Collection<Dirent> readdir(Path path, boolean followSymlinks) throws IOException {
        Collection<Dirent> defaultResult = super.readdir(path, followSymlinks);
        return transformer.readdir(defaultResult, path, followSymlinks);
      }
    };
  }

  /**
   * Test that a child with an inconsistent stat (first a directory, then not) does not prevent
   * evaluation of the remaining packages beneath a directory and the return of a partial result.
   */
  @Test
  public void testBadStatKeepGoing() throws Exception {
    reporter.removeHandler(failFastHandler);
    getSkyframeExecutor().turnOffSyscallCacheForTesting();
    // Given a package, "parent",
    Path parent = scratch.file("parent/BUILD", "sh_library(name = 'parent')").getParentDirectory();
    // And a child, "badstat",
    FileSystemUtils.createDirectoryAndParents(parent.getRelative("badstat"));

    // Such that badstat first reports that it is a directory, and then reports that it isn't,
    this.transformer = createInconsistentFileStateTransformer("parent/badstat");

    // When we find all the targets beneath parent in keep_going mode, we get the valid target
    // parent:parent, even though processing badstat threw an InconsistentFilesystemException,
    Truth.assertThat(parseListKeepGoing("//parent/...").getFirst())
        .containsExactlyElementsIn(labels("//parent:parent"));

    // And the TargetPatternEvaluator reported the expected ERROR event to the handler.
    assertContainsEvent(
        "Failed to get information about path, for parent/badstat, skipping: Inconsistent "
            + "filesystem operations",
        ImmutableSet.of(EventKind.ERROR));
  }

  /**
   * Test that a package subdirectory that throws an IOException when it is listed via readdir
   * does not prevent evaluation of the remaining packages beneath a directory and the return of
   * a partial result.
   */
  @Test
  public void testBadReaddirKeepGoing() throws Exception {
    reporter.removeHandler(failFastHandler);
    skyframeExecutor.turnOffSyscallCacheForTesting();
    // Given a package, "parent",
    Path parent = scratch.file("parent/BUILD", "sh_library(name = 'parent')").getParentDirectory();
    // And a child, "badstat",
    FileSystemUtils.createDirectoryAndParents(parent.getRelative("badstat"));

    // Such that badstat reports that it is a directory, but throws an error when its Dirents are
    // collected,
    this.transformer = createBadDirectoryListingTransformer("parent/badstat");

    // When we find all the targets beneath parent in keep_going mode, we get the valid target
    // parent:parent, even though processing badstat threw an IOException,
    Truth.assertThat(parseListKeepGoing("//parent/...").getFirst())
        .containsExactlyElementsIn(labels("//parent:parent"));

    // And the TargetPatternEvaluator reported the expected ERROR event to the handler.
    assertContainsEvent(
        "Failed to list directory contents, for parent/badstat, skipping: Path ended in "
            + "parent/badstat, so readdir failed",
        ImmutableSet.of(EventKind.ERROR));
  }

  private Transformer createInconsistentFileStateTransformer(final String badPathSuffix) {
    final AtomicBoolean isDirectory = new AtomicBoolean(true);
    return new Transformer() {
      @Nullable
      @Override
      public FileStatus stat(final FileStatus stat, Path path, boolean followSymlinks)
          throws IOException {
        if (path.getPathString().endsWith(badPathSuffix)) {
          return new InMemoryContentInfo(BlazeClock.instance()) {
            @Override
            public boolean isDirectory() {
              // Trigger inconsistent filesystem exception.
              return isDirectory.getAndSet(false);
            }

            @Override
            public boolean isFile() {
              return stat.isFile();
            }

            @Override
            public boolean isSpecialFile() {
              return stat.isSpecialFile();
            }

            @Override
            public boolean isSymbolicLink() {
              return stat.isSymbolicLink();
            }

            @Override
            public long getSize()  {
              try {
                return stat.getSize();
              } catch (IOException e) {
                throw new IllegalStateException(e);
              }
            }

            @Override
            public synchronized long getLastModifiedTime() {
              try {
                return stat.getLastModifiedTime();
              } catch (IOException e) {
                throw new IllegalStateException(e);
              }
            }

            @Override
            public synchronized long getLastChangeTime() {
              try {
                return stat.getLastChangeTime();
              } catch (IOException e) {
                throw new IllegalStateException(e);
              }
            }

            @Override
            public long getNodeId() {
              try {
                return stat.getNodeId();
              } catch (IOException e) {
                throw new IllegalStateException(e);
              }
            }
          };
        }
        return stat;
      }
    };
  }

  private Transformer createBadDirectoryListingTransformer(final String badPathSuffix) {
    return new Transformer() {
      @Nullable
      @Override
      public Collection<Dirent> readdir(Collection<Dirent> readdir, Path path,
          boolean followSymlinks) throws IOException {
        if (path.getPathString().endsWith(badPathSuffix)) {
          throw new IOException("Path ended in " + badPathSuffix + ", so readdir failed.");
        }
        return readdir;
      }
    };
  }
}
