/*
 * 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.io;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.CharMatcher;
import com.google.common.base.Charsets;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Objects;
import com.google.common.collect.Lists;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileTime;
import java.nio.file.attribute.PosixFilePermission;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public final class MoreFiles {

  // Unix has two illegal characters - '/', and '\0'.  Windows has ten, which includes those two.
  // The full list can be found at https://msdn.microsoft.com/en-us/library/aa365247
  private static final String ILLEGAL_FILE_NAME_CHARACTERS = "<>:\"/\\|?*\0";

  private static class FileAccessedEntry {
    public final File file;
    public final FileTime lastAccessTime;

    public File getFile() {
      return file;
    }

    public FileTime getLastAccessTime() {
      return lastAccessTime;
    }

    private FileAccessedEntry(File file, FileTime lastAccessTime) {
      this.file = file;
      this.lastAccessTime = lastAccessTime;
    }
  }

  /**
   * Sorts by the lastAccessTime in descending order (more recently accessed files are first).
   */
  private static final Comparator<FileAccessedEntry> SORT_BY_LAST_ACCESSED_TIME_DESC =
      new Comparator<FileAccessedEntry>() {
    @Override
    public int compare(FileAccessedEntry a, FileAccessedEntry b) {
      return b.getLastAccessTime().compareTo(a.getLastAccessTime());
    }
  };

  /** Utility class: do not instantiate. */
  private MoreFiles() {}

  public static void rmdir(Path path) throws IOException {
    try {
      deleteRecursively(path);
    } catch (NoSuchFileException e) {
      // Delete anyway even if the directory does not exist
      // This behavior is the same as rm -rf
      return;
    }
  }

  /**
   * Recursively copies all files under {@code fromPath} to {@code toPath}.
   */
  public static void copyRecursively(
      final Path fromPath,
      final Path toPath) throws IOException {
    copyRecursively(fromPath, toPath, Functions.<Path>identity());
  }

  /**
   * Recursively copies all files under {@code fromPath} to {@code toPath}.
   * The {@code transform} will be applied after the destination path for a file has been
   * relativized.
   * @param fromPath item to copy
   * @param toPath destination of copy
   * @param transform renaming function to apply when copying. If this function returns null, then
   *     the file is not copied.
   */
  public static void copyRecursively(
      final Path fromPath,
      final Path toPath,
      final Function<Path, Path> transform) throws IOException {
    // Adapted from http://codingjunkie.net/java-7-copy-move/.
    SimpleFileVisitor<Path> copyDirVisitor = new SimpleFileVisitor<Path>() {

      @Override
      public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs)
          throws IOException {
        Path targetPath = toPath.resolve(fromPath.relativize(dir));
        if (!Files.exists(targetPath)) {
          Files.createDirectory(targetPath);
        }
        return FileVisitResult.CONTINUE;
      }

      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Path destPath = toPath.resolve(fromPath.relativize(file));
        Path transformedDestPath = transform.apply(destPath);
        if (transformedDestPath != null) {
          if (Files.isSymbolicLink(file)) {
            Files.deleteIfExists(transformedDestPath);
            Files.createSymbolicLink(
                transformedDestPath,
                Files.readSymbolicLink(file));
          } else {
            Files.copy(
                file,
                transformedDestPath,
                StandardCopyOption.REPLACE_EXISTING);
          }
        }
        return FileVisitResult.CONTINUE;
      }
    };
    Files.walkFileTree(fromPath, copyDirVisitor);
  }

  public static void deleteRecursively(final Path path) throws IOException {
    // Adapted from http://codingjunkie.net/java-7-copy-move/.
    SimpleFileVisitor<Path> deleteDirVisitor = new SimpleFileVisitor<Path>() {

      @Override
      public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        Files.delete(file);
        return FileVisitResult.CONTINUE;
      }

      @Override
      public FileVisitResult postVisitDirectory(Path dir, IOException e) throws IOException {
        if (e == null) {
          Files.delete(dir);
          return FileVisitResult.CONTINUE;
        } else {
          throw e;
        }
      }
    };
    Files.walkFileTree(path, deleteDirVisitor);
  }

  /**
   * Writes the specified lines to the specified file, encoded as UTF-8.
   */
  public static void writeLinesToFile(Iterable<String> lines, File file)
      throws IOException {
    try (BufferedWriter writer = Files.newBufferedWriter(file.toPath(), Charsets.UTF_8)) {
      for (String line : lines) {
        writer.write(line);
        writer.newLine();
      }
    }
  }

  /**
   * Log a simplistic diff between lines and the contents of file.
   */
  @VisibleForTesting
  static List<String> diffFileContents(Iterable<String> lines, File file) throws IOException {
    List<String> diffLines = Lists.newArrayList();
    Iterator<String> iter = lines.iterator();
    try (BufferedReader reader = Files.newBufferedReader(file.toPath(), Charsets.UTF_8)) {
      while (iter.hasNext()) {
        String lineA = reader.readLine();
        String lineB = iter.next();
        if (!Objects.equal(lineA, lineB)) {
          diffLines.add(String.format("| %s | %s |", lineA == null ? "" : lineA, lineB));
        }
      }

      String lineA;
      while ((lineA = reader.readLine()) != null) {
        diffLines.add(String.format("| %s |  |", lineA));
      }
    }
    return diffLines;
  }

  /**
   * Does an in-place sort of the specified {@code files} array. Most recently accessed files will
   * be at the front of the array when sorted.
   */
  public static void sortFilesByAccessTime(File[] files) {
    FileAccessedEntry[] fileAccessedEntries = new FileAccessedEntry[files.length];
    for (int i = 0; i < files.length; ++i) {
      FileTime lastAccess;
      try {
        lastAccess = Files.readAttributes(
            files[i].toPath(),
            BasicFileAttributes.class).lastAccessTime();
      } catch (IOException e) {
        lastAccess = FileTime.fromMillis(files[i].lastModified());
      }
      fileAccessedEntries[i] = new FileAccessedEntry(files[i], lastAccess);
    }
    Arrays.sort(fileAccessedEntries, SORT_BY_LAST_ACCESSED_TIME_DESC);

    for (int i = 0; i < files.length; i++) {
      files[i] = fileAccessedEntries[i].getFile();
    }
  }

  /**
   * Tries to make the specified file executable. For file systems that do support the POSIX-style
   * permissions, the executable permission is set for each category of users that already has the
   * read permission.
   *
   * If the file system does not support the executable permission or the operation fails,
   * a {@code java.io.IOException} is thrown.
   */
  public static void makeExecutable(File file) throws IOException {
    if (FileSystems.getDefault().supportedFileAttributeViews().contains("posix")) {
      Path path = file.toPath();
      Set<PosixFilePermission> permissions = Files.getPosixFilePermissions(path);

      if (permissions.contains(PosixFilePermission.OWNER_READ)) {
        permissions.add(PosixFilePermission.OWNER_EXECUTE);
      }
      if (permissions.contains(PosixFilePermission.GROUP_READ)) {
        permissions.add(PosixFilePermission.GROUP_EXECUTE);
      }
      if (permissions.contains(PosixFilePermission.OTHERS_READ)) {
        permissions.add(PosixFilePermission.OTHERS_EXECUTE);
      }

      Files.setPosixFilePermissions(path, permissions);
    } else {
      if (!file.setExecutable(/* executable */ true, /* ownerOnly */ true)) {
        throw new IOException("The file could not be made executable");
      }
    }
  }

  /**
   * Given a file name, replace any illegal characters from it.
   * @param name The file name to sanitize
   * @return a properly sanitized filename
   */
  public static String sanitize(String name) {
    return CharMatcher.anyOf(ILLEGAL_FILE_NAME_CHARACTERS).replaceFrom(name, "_");
  }
}
