/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * 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.intellij.openapi.util.io;

import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.*;
import java.net.URL;
import java.util.Locale;
import java.util.Set;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import static org.junit.Assert.*;

public class IoTestUtil {
  private IoTestUtil() { }

  @NotNull
  public static File createSymLink(@NotNull String target, @NotNull String link) throws InterruptedException, IOException {
    return createSymLink(target, link, true);
  }

  @NotNull
  public static File createSymLink(@NotNull String target, @NotNull String link, boolean shouldExist) throws InterruptedException, IOException {
    assertTrue(SystemInfo.isWindows || SystemInfo.isUnix);

    final File targetFile = new File(FileUtil.toSystemDependentName(target));
    final File linkFile = getFullLinkPath(link);

    final ProcessBuilder command;
    if (SystemInfo.isWindows) {
      command = targetFile.isDirectory()
                ? new ProcessBuilder("cmd", "/C", "mklink", "/D", linkFile.getPath(), targetFile.getPath())
                : new ProcessBuilder("cmd", "/C", "mklink", linkFile.getPath(), targetFile.getPath());
    }
    else {
      command = new ProcessBuilder("ln", "-s", targetFile.getPath(), linkFile.getPath());
    }
    final int res = runCommand(command);
    assertEquals(command.command().toString(), 0, res);

    shouldExist |= SystemInfo.isWindows && SystemInfo.JAVA_VERSION.startsWith("1.6");
    assertEquals("target=" + target + ", link=" + linkFile, shouldExist, linkFile.exists());
    return linkFile;
  }

  @NotNull
  public static File createHardLink(@NotNull String target, @NotNull String link) throws InterruptedException, IOException {
    assertTrue(SystemInfo.isWindows || SystemInfo.isUnix);

    final File targetFile = new File(FileUtil.toSystemDependentName(target));
    final File linkFile = getFullLinkPath(link);

    final ProcessBuilder command;
    if (SystemInfo.isWindows) {
      command = new ProcessBuilder("fsutil", "hardlink", "create", linkFile.getPath(), targetFile.getPath());
    }
    else {
      command = new ProcessBuilder("ln", targetFile.getPath(), linkFile.getPath());
    }
    final int res = runCommand(command);
    assertEquals(command.command().toString(), 0, res);

    assertTrue("target=" + target + ", link=" + linkFile, linkFile.exists());
    return linkFile;
  }

  @NotNull
  public static File createJunction(@NotNull String target, @NotNull String junction) throws InterruptedException, IOException {
    assertTrue(SystemInfo.isWindows);

    final File targetFile = new File(FileUtil.toSystemDependentName(target));
    assertTrue(targetFile.getPath(), targetFile.isDirectory());

    final String exePath = getJunctionExePath();

    final File junctionFile = getFullLinkPath(junction);

    final ProcessBuilder command = new ProcessBuilder(exePath, junctionFile.getPath(), targetFile.getPath());
    final int res = runCommand(command);
    assertEquals(command.command().toString(), 0, res);

    assertTrue("target=" + target + ", link=" + junctionFile, junctionFile.isDirectory());
    return junctionFile;
  }

  @NotNull
  public static File createSubst(@NotNull String target) throws InterruptedException, IOException {
    assertTrue(SystemInfo.isWindows);

    final File targetFile = new File(FileUtil.toSystemDependentName(target));
    assertTrue(targetFile.getPath(), targetFile.isDirectory());

    final String substRoot = getFirstFreeDriveLetter() + ":";

    final ProcessBuilder command = new ProcessBuilder("subst", substRoot, targetFile.getPath());
    final int res = runCommand(command);
    assertEquals(command.command().toString(), 0, res);

    final File rootFile = new File(substRoot + "\\");
    assertTrue("target=" + target + ", subst=" + rootFile, rootFile.isDirectory());
    return rootFile;
  }

  public static void deleteSubst(@NotNull String substRoot) throws InterruptedException, IOException {
    runCommand(new ProcessBuilder("subst", StringUtil.trimEnd(substRoot, "\\"), "/d"));
  }

  private static char getFirstFreeDriveLetter() {
    final Set<Character> roots = ContainerUtil.map2Set(File.listRoots(), new Function<File, Character>() {
      @Override
      public Character fun(File root) {
        return root.getPath().toUpperCase(Locale.US).charAt(0);
      }
    });

    char drive = 0;
    for (char c = 'E'; c <= 'Z'; c++) {
      if (!roots.contains(c)) {
        drive = c;
        break;
      }
    }

    assertFalse("Occupied: " + roots.toString(), drive == 0);
    return drive;
  }

  private static File getFullLinkPath(String link) {
    File linkFile = new File(FileUtil.toSystemDependentName(link));
    if (!linkFile.isAbsolute()) {
      linkFile = new File(FileUtil.getTempDirectory(), link);
    }
    assertTrue(link, !linkFile.exists() || linkFile.delete());
    final File parentDir = linkFile.getParentFile();
    assertTrue("link=" + link + ", parent=" + parentDir, parentDir != null && (parentDir.isDirectory() || parentDir.mkdirs()));
    return linkFile;
  }

  private static String getJunctionExePath() throws IOException, InterruptedException {
    final URL url = IoTestUtil.class.getClassLoader().getResource("junction.exe");
    assertNotNull(url);

    final String path = url.getFile();
    final File util = new File(path);
    assertTrue(util.exists());

    final ProcessBuilder command = new ProcessBuilder(path, "/acceptEULA");
    final int res = runCommand(command);
    assertEquals(command.command().toString(), -1, res);

    return path;
  }

  private static int runCommand(final ProcessBuilder command) throws IOException, InterruptedException {
    final Process process = command.start();
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          final BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
          try {
            //noinspection StatementWithEmptyBody
            while (reader.readLine() != null);
          }
          finally {
            reader.close();
          }
        }
        catch (IOException e) {
          throw new RuntimeException(e);
        }
      }
    }).start();
    return process.waitFor();
  }

  public static void assertTimestampsEqual(final long expected, final long actual) {
    final long roundedExpected = (expected / 1000) * 1000;
    final long roundedActual = (actual / 1000) * 1000;
    assertEquals("expected: " + expected + ", actual: " + actual,
                 roundedExpected, roundedActual);
  }

  public static void assertTimestampsNotEqual(final long expected, final long actual) {
    final long roundedExpected = (expected / 1000) * 1000;
    final long roundedActual = (actual / 1000) * 1000;
    assertTrue("(un)expected: " + expected + ", actual: " + actual,
               roundedExpected != roundedActual);
  }

  @NotNull
  public static File createTestJar() throws IOException {
    File jarFile = FileUtil.createTempFile("test.", ".jar");
    return createTestJar(jarFile);
  }

  @NotNull
  public static File createTestJar(File jarFile) throws IOException {
    return createTestJar(jarFile, JarFile.MANIFEST_NAME, "");
  }

  @NotNull
  public static File createTestJar(@NotNull File jarFile, @NotNull String... data) throws IOException {
    ZipOutputStream stream = new ZipOutputStream(new FileOutputStream(jarFile));
    try {
      for (int i = 0; i < data.length; i += 2) {
        stream.putNextEntry(new ZipEntry(data[i]));
        stream.write(data[i + 1].getBytes("UTF-8"));
        stream.closeEntry();
      }
    }
    finally {
      stream.close();
    }
    return jarFile;
  }

  @NotNull
  public static File createTestDir(@NotNull String name) {
    return createTestDir(new File(FileUtil.getTempDirectory()), name);
  }

  @NotNull
  public static File createTestDir(@NotNull File parent, @NotNull String name) {
    File dir = new File(parent, name);
    assertTrue(dir.getPath(), dir.mkdirs());
    return dir;
  }

  @NotNull
  public static File createTestFile(@NotNull String name) throws IOException {
    return createTestFile(name, null);
  }

  @NotNull
  public static File createTestFile(@NotNull String name, @Nullable String content) throws IOException {
    return createTestFile(new File(FileUtil.getTempDirectory()), name, content);
  }

  @NotNull
  public static File createTestFile(@NotNull File parent, @NotNull String name) throws IOException {
    return createTestFile(parent, name, null);
  }

  @NotNull
  public static File createTestFile(@NotNull File parent, @NotNull String name, @Nullable String content) throws IOException {
    assertTrue(parent.getPath(), parent.isDirectory() || parent.mkdirs());
    File file = new File(parent, name);
    assertTrue(file.getPath(), file.createNewFile());
    if (content != null) {
      FileUtil.writeToFile(file, content);
    }
    return file;
  }

  public static void delete(File... files) {
    for (File file : files) {
      if (file != null) {
        FileUtil.delete(file);
      }
    }
  }

  public static void setHidden(@NotNull String path, boolean hidden) throws IOException, InterruptedException {
    assertTrue(SystemInfo.isWindows);

    ProcessBuilder command = new ProcessBuilder("attrib", hidden ? "+H" : "-H", path);
    int res = runCommand(command);
    assertEquals(command.command().toString(), 0, res);
  }
}
