// 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.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.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.CustomLibrarySpecification;
import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousFileChannel;
import java.nio.channels.FileChannel;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.ProviderMismatchException;
import java.nio.file.StandardOpenOption;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class ChannelSetTest extends DesugaredLibraryTestBase {

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

  private static final String EXPECTED_RESULT_DESUGARING =
      StringUtils.lines(
          "bytes written: 11",
          "String written: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "unsupported");
  private static final String EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM =
      StringUtils.lines(
          "bytes written: 11",
          "String written: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World");
  private static final String EXPECTED_RESULT_NO_DESUGARING =
      StringUtils.lines(
          "bytes written: 11",
          "String written: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "wrapper start",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World",
          "bytes read: 11",
          "String read: Hello World");

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

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

  @Test
  public void test() throws Throwable {
    testForDesugaredLibrary(parameters, libraryDesugaringSpecification, compilationSpecification)
        .addProgramClasses(TestClass.class)
        .setCustomLibrarySpecification(
            new CustomLibrarySpecification(CustomLib.class, AndroidApiLevel.B))
        .addKeepMainRule(TestClass.class)
        .compile()
        .withArt6Plus64BitsLib()
        .run(
            parameters.getRuntime(),
            TestClass.class,
            Integer.toString(parameters.getApiLevel().getLevel()))
        .assertSuccessWithOutput(getExpectedResult());
  }

  private String getExpectedResult() {
    if (!libraryDesugaringSpecification.hasNioFileDesugaring(parameters)) {
      return EXPECTED_RESULT_NO_DESUGARING;
    }
    return libraryDesugaringSpecification.usesPlatformFileSystem(parameters)
        ? EXPECTED_RESULT_DESUGARING_PLATFORM_FILE_SYSTEM
        : EXPECTED_RESULT_DESUGARING;
  }

  public static class CustomLib {

    // Answers effectively a Path wrapper.
    public static Path get(String path) {
      return Paths.get(path);
    }
  }

  public static class TestClass {

    public static void main(String[] args) throws Throwable {
      Path path = Files.createTempFile("example", ".txt");
      String hello = "Hello World";
      Set<OpenOption> openOptions = new HashSet<>();
      openOptions.add(LinkOption.NOFOLLOW_LINKS);
      writeHelloWorldIntoFile(path, hello);
      readHelloWithPathApis(path, hello, openOptions);
      // The rest of tests are testing API conversion, which is possible only on + devices.
      if (Integer.parseInt(args[0]) < 26) {
        return;
      }
      System.out.println("wrapper start");
      Path pathWrapper = CustomLib.get(path.toString());
      readHelloWithPathWrapperApis(pathWrapper, hello, openOptions);
      try {
        try (SeekableByteChannel channel =
            pathWrapper.getFileSystem().provider().newByteChannel(path, openOptions)) {
          readFromChannel(channel, hello.length());
        }
      } catch (ProviderMismatchException e) {
        System.out.println("provider missmatch");
      }
    }

    private static void readHelloWithPathWrapperApis(
        Path pathWrapper, String hello, Set<OpenOption> openOptions)
        throws IOException, InterruptedException, ExecutionException {
      try (SeekableByteChannel channel =
          pathWrapper.getFileSystem().provider().newByteChannel(pathWrapper, openOptions)) {
        readFromChannel(channel, hello.length());
      }
      try (FileChannel channel =
          pathWrapper.getFileSystem().provider().newFileChannel(pathWrapper, openOptions)) {
        readFromChannel(channel, hello.length());
      }
      ExecutorService executor;
      try {
        executor = ForkJoinPool.commonPool();
      } catch (Throwable t) {
        // ForkJoinPool is not entirely supported below Android 5.
        System.out.println("unsupported");
        return;
      }
      try {
        try (AsynchronousFileChannel channel =
            pathWrapper
                .getFileSystem()
                .provider()
                .newAsynchronousFileChannel(pathWrapper, openOptions, executor)) {
          ByteBuffer byteBuffer = ByteBuffer.allocate(hello.length());
          Future<Integer> readFuture = channel.read(byteBuffer, 0);
          // We force the future to await here with get().
          int read = readFuture.get();
          System.out.println("bytes read: " + read);
          System.out.println("String read: " + new String(byteBuffer.array()));
        }
      } catch (UnsupportedOperationException e) {
        System.out.println("unsupported");
      }
    }

    private static void readHelloWithPathApis(Path path, String hello, Set<OpenOption> openOptions)
        throws IOException, InterruptedException, ExecutionException {
      try (SeekableByteChannel channel =
          path.getFileSystem().provider().newByteChannel(path, openOptions)) {
        readFromChannel(channel, hello.length());
      }
      try (FileChannel channel =
          path.getFileSystem().provider().newFileChannel(path, openOptions)) {
        readFromChannel(channel, hello.length());
      }
      try {
        try (AsynchronousFileChannel channel =
            path.getFileSystem()
                .provider()
                .newAsynchronousFileChannel(path, openOptions, ForkJoinPool.commonPool())) {
          ByteBuffer byteBuffer = ByteBuffer.allocate(hello.length());
          Future<Integer> readFuture = channel.read(byteBuffer, 0);
          int read = readFuture.get();
          System.out.println("bytes read: " + read);
          System.out.println("String read: " + new String(byteBuffer.array()));
        }
      } catch (NoClassDefFoundError | UnsupportedOperationException e) {
        // ForkJoinPool is missing (officially below Android 21, in practice somewhere below).
        // The method newAsynchronousFileChannel is unsupported on DesugarFileSystems.
        System.out.println("unsupported");
      }
    }

    private static void writeHelloWorldIntoFile(Path path, String hello) throws IOException {
      try (SeekableByteChannel channel =
          Files.newByteChannel(path, StandardOpenOption.READ, StandardOpenOption.WRITE)) {
        ByteBuffer byteBuffer = ByteBuffer.wrap(hello.getBytes());
        int write = channel.write(byteBuffer);
        System.out.println("bytes written: " + write);
        System.out.println("String written: " + hello);
      }
    }

    private static void readFromChannel(SeekableByteChannel channel, int helloWorldSize)
        throws IOException {
      ByteBuffer byteBuffer = ByteBuffer.allocate(helloWorldSize);
      int read = channel.read(byteBuffer);
      System.out.println("bytes read: " + read);
      System.out.println("String read: " + new String(byteBuffer.array()));
    }
  }
}
