// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.android.tools.r8.desugar.desugaredlibrary.jdk11;

import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.CopyOrMove.COPY;
import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.CopyOrMove.COPY_FROM_INPUT_STREAM;
import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.CopyOrMove.COPY_TO_OUTPUT_STREAM;
import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.CopyOrMove.MOVE;
import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.NewFile.EXISTING;
import static com.android.tools.r8.desugar.desugaredlibrary.jdk11.FilesMoveCopyTest.TestClass.NewFile.NEW;
import static com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification.DEFAULT_SPECIFICATIONS;
import static com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.JDK11_PATH;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.desugar.desugaredlibrary.test.CompilationSpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.CopyOption;
import java.nio.file.FileAlreadyExistsException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.nio.file.StandardOpenOption;
import java.util.List;
import org.junit.Assume;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/**
 * Tests Files#copy and Files#move methods. Known limitations/details below 26: - ATOMIC MOVE is a
 * no-op, moves are effectively file renaming which seem to be atomic on Android. - COPY_ATTRIBUTES
 * is a no-op, except if unsupported in which case it throws appropriately, now it seems only basic
 * file attributes are supported below 26 anyway and such attributes are not meaningfully copied
 * around anyway. Creation/last modification/last access times are set to the time of the move/copy,
 * and the other ones such as "isDirectory" cannot be easily abused.
 */
@RunWith(Parameterized.class)
public class FilesMoveCopyTest extends DesugaredLibraryTestBase {

  private static final String EXPECTED_RESULT_FORMAT =
      StringUtils.lines(
          "Testing COPY_TO_OUTPUT_STREAM EXISTING NONE",
          "COPY_TO_OUTPUT_STREAM_NONE",
          "Testing MOVE NEW NONE",
          "MOVE_NONE",
          "Testing COPY NEW NONE",
          "COPY_NONE",
          "Testing COPY_FROM_INPUT_STREAM NEW NONE",
          "COPY_FROM_INPUT_STREAM_NONE",
          "Testing MOVE EXISTING NONE",
          "Failure: class java.nio.file.FileAlreadyExistsException :: dest",
          "Testing COPY EXISTING NONE",
          "Failure: class java.nio.file.FileAlreadyExistsException :: dest",
          "Testing COPY_FROM_INPUT_STREAM EXISTING NONE",
          "%s",
          "Testing MOVE NEW ATOMIC_MOVE",
          "MOVE_ATOMIC_MOVE",
          "Testing COPY NEW ATOMIC_MOVE",
          "Failure: class java.lang.UnsupportedOperationException :: Unsupported copy option",
          "Testing COPY_FROM_INPUT_STREAM NEW ATOMIC_MOVE",
          "Failure: class java.lang.UnsupportedOperationException :: ATOMIC_MOVE not supported",
          "Testing MOVE NEW COPY_ATTRIBUTES",
          "Failure: class java.lang.UnsupportedOperationException :: Unsupported copy option",
          "Testing COPY NEW COPY_ATTRIBUTES",
          "COPY_COPY_ATTRIBUTES",
          "Testing COPY_FROM_INPUT_STREAM NEW COPY_ATTRIBUTES",
          "Failure: class java.lang.UnsupportedOperationException :: COPY_ATTRIBUTES not supported",
          "Testing MOVE NEW REPLACE_EXISTING",
          "MOVE_REPLACE_EXISTING",
          "Testing COPY NEW REPLACE_EXISTING",
          "COPY_REPLACE_EXISTING",
          "Testing COPY_FROM_INPUT_STREAM NEW REPLACE_EXISTING",
          "COPY_FROM_INPUT_STREAM_REPLACE_EXISTING",
          "Testing MOVE EXISTING REPLACE_EXISTING",
          "MOVE_REPLACE_EXISTING",
          "Testing COPY EXISTING REPLACE_EXISTING",
          "COPY_REPLACE_EXISTING",
          "Testing COPY_FROM_INPUT_STREAM EXISTING REPLACE_EXISTING",
          "COPY_FROM_INPUT_STREAM_REPLACE_EXISTING",
          "Testing MOVE NEW NOFOLLOW_LINKS",
          "MOVE_NOFOLLOW_LINKS",
          "Testing COPY NEW NOFOLLOW_LINKS",
          "COPY_NOFOLLOW_LINKS",
          "Testing COPY_FROM_INPUT_STREAM NEW NOFOLLOW_LINKS",
          "Failure: class java.lang.UnsupportedOperationException :: NOFOLLOW_LINKS not supported");

  private final TestParameters parameters;
  private final LibraryDesugaringSpecification libraryDesugaringSpecification;
  private final CompilationSpecification compilationSpecification;

  @Parameters(name = "{0}, spec: {1}, {2}")
  public static List<Object[]> data() {
    return buildParameters(
        // Skip Android 4.4.4 due to missing libjavacrypto.
        getTestParameters()
            .withCfRuntime(CfVm.JDK11)
            .withDexRuntimesStartingFromIncluding(Version.V8_1_0)
            .withAllApiLevels()
            .build(),
        ImmutableList.of(JDK11_PATH),
        DEFAULT_SPECIFICATIONS);
  }

  public FilesMoveCopyTest(
      TestParameters parameters,
      LibraryDesugaringSpecification libraryDesugaringSpecification,
      CompilationSpecification compilationSpecification) {
    this.parameters = parameters;
    this.libraryDesugaringSpecification = libraryDesugaringSpecification;
    this.compilationSpecification = compilationSpecification;
  }

  private String getExpectedResult() {
    // TODO(b/260208125): Fix invalid behavior.
    // When copying from the input stream into an existing file and no options,
    // the desugared version succeeds by deleting the file while the regular version fails
    // with FileAlreadyExistsException exception.
    String result =
        (parameters.isDexRuntime()
                && !libraryDesugaringSpecification.usesPlatformFileSystem(parameters))
            ? "COPY_FROM_INPUT_STREAM_NONE"
            : "Failure: class java.nio.file.FileAlreadyExistsException :: dest";
    return String.format(EXPECTED_RESULT_FORMAT, result);
  }

  @Test
  public void test() throws Throwable {
    if (parameters.isCfRuntime()) {
      // Reference runtime, we use Jdk 11 since this is Jdk 11 desugared library, not that Jdk 8
      // behaves differently on this test.
      Assume.assumeTrue(parameters.isCfRuntime(CfVm.JDK11) && !ToolHelper.isWindows());
      testForJvm()
          .addInnerClasses(getClass())
          .run(parameters.getRuntime(), TestClass.class)
          .assertSuccessWithOutput(getExpectedResult());
      return;
    }
    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
        .addInnerClasses(getClass())
        .addKeepMainRule(TestClass.class)
        .compile()
        .withArt6Plus64BitsLib()
        .run(parameters.getRuntime(), TestClass.class)
        .assertSuccessWithOutput(getExpectedResult());
  }

  public static class TestClass {

    enum CopyOrMove {
      COPY,
      COPY_FROM_INPUT_STREAM,
      COPY_TO_OUTPUT_STREAM,
      MOVE
    }

    enum NewFile {
      EXISTING,
      NEW
    }

    public static void main(String[] args) throws Throwable {
      test(COPY_TO_OUTPUT_STREAM, EXISTING, null);
      for (CopyOption copyOption : allOptions()) {
        test(MOVE, NEW, copyOption);
        test(COPY, NEW, copyOption);
        test(COPY_FROM_INPUT_STREAM, NEW, copyOption);
        if (copyOption == null || copyOption == StandardCopyOption.REPLACE_EXISTING) {
          test(MOVE, EXISTING, copyOption);
          test(COPY, EXISTING, copyOption);
          test(COPY_FROM_INPUT_STREAM, EXISTING, copyOption);
        }
      }
    }

    private static CopyOption[] allOptions() {
      return new CopyOption[] {
        null,
        StandardCopyOption.ATOMIC_MOVE,
        StandardCopyOption.COPY_ATTRIBUTES,
        StandardCopyOption.REPLACE_EXISTING,
        LinkOption.NOFOLLOW_LINKS
      };
    }

    private static void clearTmp(Path src, Path dest) throws IOException {
      if (Files.exists(src)) {
        Files.delete(src);
      }
      if (Files.exists(dest)) {
        Files.delete(dest);
      }
    }

    private static void test(CopyOrMove copyOrMove, NewFile newFile, CopyOption copyOption)
        throws IOException {
      String copyOptionString = copyOption == null ? "NONE" : copyOption.toString();
      CopyOption[] opts = copyOption == null ? new CopyOption[0] : new CopyOption[] {copyOption};
      System.out.println("Testing " + copyOrMove + " " + newFile + " " + copyOptionString);
      Path src = Files.createTempFile("src_", ".txt");
      Path dest =
          newFile == NEW
              ? src.getParent().resolve("dest_" + System.currentTimeMillis() + ".txt")
              : Files.createTempFile("dest_", ".txt");
      String toWrite = copyOrMove + "_" + copyOptionString;
      Files.write(src, toWrite.getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE);
      try {
        switch (copyOrMove) {
          case COPY:
            Files.copy(src, dest, opts);
            break;
          case MOVE:
            Files.move(src, dest, opts);
            break;
          case COPY_FROM_INPUT_STREAM:
            FileInputStream in = new FileInputStream(src.toFile());
            Files.copy(in, dest, opts);
            in.close();
            break;
          case COPY_TO_OUTPUT_STREAM:
            if (opts.length != 0) {
              throw new UnsupportedOperationException("Api does not encode options");
            }
            FileOutputStream out = new FileOutputStream(dest.toFile());
            Files.copy(src, out);
            out.close();
            break;
        }
        System.out.println(Files.readAllLines(dest).get(0));
      } catch (Throwable t) {
        String subMessage;
        if (t instanceof FileAlreadyExistsException && t.getMessage() != null) {
          // The message is the file path, however we cannot rely on temp path, so we check
          // only against the known part of the path.
          String[] split = t.getMessage().split("/");
          subMessage = split[split.length - 1].substring(0, 4);
        } else {
          subMessage = t.getMessage();
        }
        System.out.println("Failure: " + t.getClass() + " :: " + subMessage);
      }
      clearTmp(src, dest);
    }
  }
}
