// 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.LibraryDesugaringSpecification.CustomConversionVersion.LEGACY;

import com.android.tools.r8.desugar.desugaredlibrary.test.LibraryDesugaringSpecification.CustomConversionVersion;
import com.android.tools.r8.references.Reference;
import com.android.tools.r8.transformers.ClassFileTransformer;
import com.android.tools.r8.transformers.MethodTransformer;
import com.android.tools.r8.utils.StreamUtils;
import com.android.tools.r8.utils.ZipUtils;
import java.io.BufferedOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import org.objectweb.asm.Opcodes;

public class ConversionConverter {

  private static final Map<String, String> JAVA_WRAP_CONVERT_OWNER = new HashMap<>();
  private static final Map<String, String> J$_WRAP_CONVERT_OWNER = new HashMap<>();

  static {
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/spi/FileSystemProvider",
        "java/nio/file/spi/FileSystemProvider$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/spi/FileTypeDetector", "java/nio/file/spi/FileTypeDetector$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/StandardOpenOption", "java/nio/file/StandardOpenOption$EnumConversion");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/LinkOption", "java/nio/file/LinkOption$EnumConversion");
    JAVA_WRAP_CONVERT_OWNER.put("j$/nio/file/Path", "java/nio/file/Path$Wrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/WatchEvent", "java/nio/file/WatchEvent$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/BasicFileAttributes",
        "java/nio/file/attribute/BasicFileAttributes$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/BasicFileAttributeView",
        "java/nio/file/attribute/BasicFileAttributeView$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/FileOwnerAttributeView",
        "java/nio/file/attribute/FileOwnerAttributeView$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFileAttributes",
        "java/nio/file/attribute/PosixFileAttributes$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFileAttributeView",
        "java/nio/file/attribute/PosixFileAttributeView$VivifiedWrapper");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFilePermission",
        "java/nio/file/attribute/PosixFilePermission$EnumConversion");
    JAVA_WRAP_CONVERT_OWNER.put(
        "j$/util/stream/Collector$Characteristics",
        "java/util/stream/Collector$Characteristics$EnumConversion");

    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/spi/FileSystemProvider", "java/nio/file/spi/FileSystemProvider$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/spi/FileTypeDetector", "java/nio/file/spi/FileTypeDetector$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/StandardOpenOption", "java/nio/file/StandardOpenOption$EnumConversion");
    J$_WRAP_CONVERT_OWNER.put("j$/nio/file/LinkOption", "java/nio/file/LinkOption$EnumConversion");
    J$_WRAP_CONVERT_OWNER.put("j$/nio/file/Path", "java/nio/file/Path$VivifiedWrapper");
    J$_WRAP_CONVERT_OWNER.put("j$/nio/file/WatchEvent", "java/nio/file/WatchEvent$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/BasicFileAttributes",
        "java/nio/file/attribute/BasicFileAttributes$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/BasicFileAttributeView",
        "java/nio/file/attribute/BasicFileAttributeView$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/FileOwnerAttributeView",
        "java/nio/file/attribute/FileOwnerAttributeView$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFileAttributes",
        "java/nio/file/attribute/PosixFileAttributes$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFileAttributeView",
        "java/nio/file/attribute/PosixFileAttributeView$Wrapper");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/nio/file/attribute/PosixFilePermission",
        "java/nio/file/attribute/PosixFilePermission$EnumConversion");
    J$_WRAP_CONVERT_OWNER.put(
        "j$/util/stream/Collector$Characteristics",
        "java/util/stream/Collector$Characteristics$EnumConversion");
  }

  public static Path convertJar(Path jar, CustomConversionVersion legacy) {
    String fileName = jar.getFileName().toString();
    String newFileName =
        fileName.substring(0, fileName.length() - ".jar".length())
            + (legacy == LEGACY ? "_legacy" : "")
            + "_converted.jar";
    Path convertedJar = jar.getParent().resolve(newFileName);
    return internalConvert(jar, convertedJar, legacy);
  }

  private static synchronized Path internalConvert(
      Path jar, Path convertedJar, CustomConversionVersion legacy) {
    if (Files.exists(convertedJar)) {
      return convertedJar;
    }

    OpenOption[] options =
        new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
    try (ZipOutputStream out =
        new ZipOutputStream(
            new BufferedOutputStream(Files.newOutputStream(convertedJar, options)))) {
      new ConversionConverter().convert(jar, out, legacy);
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
    return convertedJar;
  }

  private void convert(
      Path desugaredLibraryFiles, ZipOutputStream out, CustomConversionVersion legacy)
      throws IOException {
    ZipUtils.iter(
        desugaredLibraryFiles,
        ((entry, input) -> {
          if (!entry.getName().endsWith(".class")) {
            return;
          }
          if (legacy == LEGACY
              && (entry.getName().contains("nio.file") || entry.getName().contains("ApiFlips"))) {
            return;
          }
          final byte[] bytes = StreamUtils.streamToByteArrayClose(input);
          final byte[] rewrittenBytes =
              transformInvoke(entry.getName().substring(0, entry.getName().length() - 6), bytes);
          ZipUtils.writeToZipStream(out, entry.getName(), rewrittenBytes, ZipEntry.STORED);
        }));
  }

  private byte[] transformInvoke(String descriptor, byte[] bytes) {
    return ClassFileTransformer.create(bytes, Reference.classFromDescriptor(descriptor))
        .addMethodTransformer(getMethodTransformer())
        .transform();
  }

  private MethodTransformer getMethodTransformer() {
    return new MethodTransformer() {
      @Override
      public void visitMethodInsn(
          int opcode, String owner, String name, String descriptor, boolean isInterface) {
        if (opcode == Opcodes.INVOKESTATIC && name.equals("wrap_convert")) {
          if (!JAVA_WRAP_CONVERT_OWNER.containsKey(owner)
              || !J$_WRAP_CONVERT_OWNER.containsKey(owner)) {
            throw new RuntimeException("Cannot transform wrap_convert method for " + owner);
          }
          if (owner.startsWith("java")) {
            String newOwner = J$_WRAP_CONVERT_OWNER.get(owner);
            super.visitMethodInsn(opcode, newOwner, "convert", descriptor, isInterface);
            return;
          } else if (owner.startsWith("j$")) {
            String newOwner = JAVA_WRAP_CONVERT_OWNER.get(owner);
            super.visitMethodInsn(opcode, newOwner, "convert", descriptor, isInterface);
            return;
          } else {
            throw new RuntimeException("Cannot transform wrap_convert method for " + owner);
          }
        }
        super.visitMethodInsn(opcode, owner, name, descriptor, isInterface);
      }
    };
  }
}
