/*
 * Copyright 2012-present Facebook, Inc.
 *
 * 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.facebook.buck.testutil.integration;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.facebook.buck.cli.Main;
import com.facebook.buck.util.CapturingPrintStream;
import com.facebook.buck.util.MoreFiles;
import com.facebook.buck.util.MoreStrings;
import com.facebook.buck.util.environment.Platform;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.io.Files;
import com.martiansoftware.nailgun.NGContext;

import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;

import javax.annotation.Nullable;

/**
 * {@link ProjectWorkspace} is a directory that contains a Buck project, complete with build files.
 * <p>
 * When {@link #setUp()} is invoked, the project files are cloned from a directory of testdata into
 * a tmp directory according to the following rule:
 * <ul>
 *   <li>Files with the {@code .expected} extension will not be copied.
 * </ul>
 * After {@link #setUp()} is invoked, the test should invoke Buck in that directory. As this is an
 * integration test, we expect that files will be written as a result of invoking Buck.
 * <p>
 * After Buck has been run, invoke {@link #verify()} to verify that Buck wrote the correct files.
 * For each file in the testdata directory with the {@code .expected} extension, {@link #verify()}
 * will check that a file with the same relative path (but without the {@code .expected} extension)
 * exists in the tmp directory. If not, {@link org.junit.Assert#fail()} will be invoked.
 */
public class ProjectWorkspace {

  private static final String EXPECTED_SUFFIX = ".expected";

  private static final Function<Path, Path> BUILD_FILE_RENAME = new Function<Path, Path>() {
    @Override
    @Nullable
    public Path apply(Path path) {
      String fileName = path.getFileName().toString();
      if (fileName.endsWith(EXPECTED_SUFFIX)) {
        return null;
      } else {
        return path;
      }
    }
  };

  private boolean isSetUp = false;
  private final Path templatePath;
  private final File destDir;
  private final Path destPath;

  /**
   * @param templateDir The directory that contains the template version of the project.
   * @param temporaryFolder The directory where the clone of the template directory should be
   *     written. By requiring a {@link TemporaryFolder} rather than a {@link File}, we can ensure
   *     that JUnit will clean up the test correctly.
   */
  public ProjectWorkspace(File templateDir, DebuggableTemporaryFolder temporaryFolder) {
    Preconditions.checkNotNull(templateDir);
    Preconditions.checkNotNull(temporaryFolder);
    this.templatePath = templateDir.toPath();
    this.destDir = temporaryFolder.getRoot();
    this.destPath = destDir.toPath();
  }

  /**
   * This will copy the template directory, renaming files named {@code BUCK.test} to {@code BUCK}
   * in the process. Files whose names end in {@code .expected} will not be copied.
   */
  public void setUp() throws IOException {
    MoreFiles.copyRecursively(templatePath, destPath, BUILD_FILE_RENAME);

    if (Platform.detect() == Platform.WINDOWS) {
      // Hack for symlinks on Windows.
      SimpleFileVisitor<Path> copyDirVisitor = new SimpleFileVisitor<Path>() {
        @Override
        public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
          // On Windows, symbolic links from git repository are checked out as normal files
          // containing a one-line path. In order to distinguish them, paths are read and pointed
          // files are trued to locate. Once the pointed file is found, it will be copied to target.
          // On NTFS length of path must be greater than 0 and less than 4096.
          if (attrs.size() > 0 && attrs.size() <= 4096) {
            File file = path.toFile();
            String linkTo = Files.toString(file, Charsets.UTF_8);
            File linkToFile = new File(templatePath.toFile(), linkTo);
            if (linkToFile.isFile()) {
              java.nio.file.Files.copy(
                  linkToFile.toPath(), path, StandardCopyOption.REPLACE_EXISTING);
            } else if (linkToFile.isDirectory()) {
              if (!file.delete()) {
                throw new IOException();
              }
              MoreFiles.copyRecursively(linkToFile.toPath(), path);
            }
          }
          return FileVisitResult.CONTINUE;
        }
      };
      java.nio.file.Files.walkFileTree(destPath, copyDirVisitor);
    }
    isSetUp = true;
  }

  /**
   * Runs Buck with the specified list of command-line arguments.
   * @param args to pass to {@code buck}, so that could be {@code ["build", "//path/to:target"]},
   *   {@code ["project"]}, etc.
   * @return the result of running Buck, which includes the exit code, stdout, and stderr.
   */
  public ProcessResult runBuckCommand(String... args) throws IOException {
    assertTrue("setUp() must be run before this method is invoked", isSetUp);
    CapturingPrintStream stdout = new CapturingPrintStream();
    CapturingPrintStream stderr = new CapturingPrintStream();

    Main main = new Main(stdout, stderr);
    int exitCode = main.runMainWithExitCode(destDir, Optional.<NGContext>absent(), args);

    return new ProcessResult(exitCode,
        stdout.getContentsAsString(Charsets.UTF_8),
        stderr.getContentsAsString(Charsets.UTF_8));
  }

  /**
   * @return the {@link File} that corresponds to the {@code pathRelativeToProjectRoot}.
   */
  public File getFile(String pathRelativeToProjectRoot) {
    return new File(destDir, pathRelativeToProjectRoot);
  }

  public String getFileContents(String pathRelativeToProjectRoot) throws IOException {
    return Files.toString(getFile(pathRelativeToProjectRoot), Charsets.UTF_8);
  }

  /**
   * @return the specified path resolved against the root of this workspace.
   */
  public Path resolve(Path pathRelativeToWorkspaceRoot) {
    return destPath.resolve(pathRelativeToWorkspaceRoot);
  }

  /** The result of running {@code buck} from the command line. */
  public static class ProcessResult {
    private final int exitCode;
    private final String stdout;
    private final String stderr;

    private ProcessResult(int exitCode, String stdout, String stderr) {
      this.exitCode = exitCode;
      this.stdout = Preconditions.checkNotNull(stdout);
      this.stderr = Preconditions.checkNotNull(stderr);
    }

    /**
     * Returns the exit code from the process.
     * <p>
     * Currently, this method is private because, in practice, any time a client might want to use
     * it, it is more appropriate to use {@link #assertExitCode(String, int)} instead. If a valid
     * use case arises, then we should make this getter public.
     */
    private int getExitCode() {
      return exitCode;
    }

    public String getStdout() {
      return stdout;
    }

    public String getStderr() {
      return stderr;
    }

    public void assertExitCode(int exitCode) {
      assertExitCode(null, exitCode);
    }

    public void assertExitCode(@Nullable String message, int exitCode) {
      if (exitCode == getExitCode()) {
        return;
      }

      String failureMessage = String.format(
          "Expected exit code %d but was %d.", exitCode, getExitCode());
      if (message != null) {
        failureMessage = message + " " + failureMessage;
      }

      System.err.println("=== " + failureMessage + " ===");
      System.err.println("=== STDERR ===");
      System.err.println(getStderr());
      System.err.println("=== STDOUT ===");
      System.err.println(getStdout());
      fail(failureMessage);
    }
  }

  /**
   * For every file in the template directory whose name ends in {@code .expected}, checks that an
   * equivalent file has been written in the same place under the destination directory.
   */
  public void verify() throws IOException {
    SimpleFileVisitor<Path> copyDirVisitor = new SimpleFileVisitor<Path>() {
      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        String fileName = file.getFileName().toString();
        if (fileName.endsWith(EXPECTED_SUFFIX)) {
          // Get File for the file that should be written, but without the ".expected" suffix.
          Path generatedFileWithSuffix = destPath.resolve(templatePath.relativize(file));
          File directory = generatedFileWithSuffix.getParent().toFile();
          File observedFile = new File(directory, Files.getNameWithoutExtension(fileName));

          if (!observedFile.isFile()) {
            fail("Expected file " + observedFile + " could not be found.");
          }
          String expectedFileContent = Files.toString(file.toFile(), Charsets.UTF_8);
          String observedFileContent = Files.toString(observedFile, Charsets.UTF_8);
          observedFileContent = observedFileContent.replace("\r\n", "\n");
          String cleanPathToObservedFile = MoreStrings.withoutSuffix(
              templatePath.relativize(file).toString(), EXPECTED_SUFFIX);
          assertEquals(
              String.format(
                  "In %s, expected content of %s to match that of %s.",
                  cleanPathToObservedFile,
                  expectedFileContent,
                  observedFileContent),
              expectedFileContent,
              observedFileContent);
        }
        return FileVisitResult.CONTINUE;
      }
    };
    java.nio.file.Files.walkFileTree(templatePath, copyDirVisitor);
  }
}
