// Copyright (c) 2021, 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.ir.optimize.instanceofremoval;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.ir.analysis.type.ClassTypeElement;
import com.android.tools.r8.ir.analysis.type.InterfaceCollection;
import com.android.tools.r8.ir.analysis.type.Nullability;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.Timing;
import com.android.tools.r8.utils.ZipUtils.ZipBuilder;
import java.io.IOException;
import java.nio.channels.Channel;
import java.nio.file.Path;
import java.util.jar.JarFile;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ZipFileInstanceOfAutoCloseableTest extends TestBase {

  static final String EXPECTED_PRE_API_19 = StringUtils.lines("Not an AutoCloseable");
  static final String EXPECTED_POST_API_19 = StringUtils.lines("Is an AutoCloseable");

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  public ZipFileInstanceOfAutoCloseableTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  private boolean runtimeZipFileIsCloseable() {
    return parameters.isCfRuntime()
        || parameters
            .getRuntime()
            .asDex()
            .maxSupportedApiLevel()
            .isGreaterThanOrEqualTo(AndroidApiLevel.K);
  }

  private String expectedOutput() {
    return runtimeZipFileIsCloseable() ? EXPECTED_POST_API_19 : EXPECTED_PRE_API_19;
  }

  private Path getAndroidJar() {
    // Always use an android jar later than API 19. Thus at compile-time ZipFile < Closeable.
    return ToolHelper.getAndroidJar(AndroidApiLevel.LATEST);
  }

  private String getZipFile() throws IOException {
    return ZipBuilder.builder(temp.newFile("file.zip").toPath())
        .addBytes("entry", new byte[1])
        .build()
        .toString();
  }

  @Test
  public void testD8() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    testForD8()
        .addInnerClasses(ZipFileInstanceOfAutoCloseableTest.class)
        .setMinApi(parameters.getApiLevel())
        .addLibraryFiles(getAndroidJar())
        .run(parameters.getRuntime(), TestClass.class, getZipFile())
        .assertSuccessWithOutput(expectedOutput());
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(ZipFileInstanceOfAutoCloseableTest.class)
        .addKeepMainRule(TestClass.class)
        .setMinApi(parameters.getApiLevel())
        .addLibraryFiles(getAndroidJar())
        .run(parameters.getRuntime(), TestClass.class, getZipFile())
        .assertSuccessWithOutput(expectedOutput());
  }

  @Test
  public void testTypeStructure() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    // Set the min API and create the raw app.
    InternalOptions options = new InternalOptions();
    options.minApiLevel = parameters.getApiLevel();
    DirectMappedDexApplication application =
        new ApplicationReader(
                AndroidApp.builder()
                    .addProgramFiles(ToolHelper.getClassFileForTestClass(MyJarFileScanner.class))
                    .addLibraryFiles(getAndroidJar())
                    .build(),
                options,
                Timing.empty())
            .read()
            .toDirect();
    AppView<AppInfoWithClassHierarchy> appView = AppView.createForR8(application);

    // Type references.
    DexType zipFileType = appView.dexItemFactory().createType("Ljava/util/zip/ZipFile;");
    DexType closeableType = appView.dexItemFactory().createType("Ljava/io/Closeable;");
    DexType autoCloseableType = appView.dexItemFactory().createType("Ljava/lang/AutoCloseable;");
    DexType scannerType = appView.dexItemFactory().createType("Ljava/util/Scanner;");
    DexType myJarFileChannel = buildType(MyJarFileScanner.class, appView.dexItemFactory());

    // Read the computed interface types. Both the "type element" which is used in IR and the full
    // computed dependencies.
    ClassTypeElement zipFileTypeElement = makeTypeElement(appView, zipFileType);
    {
      InterfaceCollection directInterfaces = zipFileTypeElement.getInterfaces();
      InterfaceCollection allInterfaces = appView.appInfo().implementedInterfaces(zipFileType);
      if (zipFileHasCloseable()) {
        // After API 19 / K the types are known and present.
        assertEquals(closeableType, directInterfaces.getSingleKnownInterface());
        assertTrue(allInterfaces.containsKnownInterface(closeableType));
        assertTrue(allInterfaces.containsKnownInterface(autoCloseableType));
        assertEquals(2, allInterfaces.size());
      } else {
        // The interfaces are still present due to the android jar for K, but they are marked
        // unknown.
        assertTrue(directInterfaces.contains(closeableType).isUnknown());
        assertFalse(directInterfaces.containsKnownInterface(closeableType));
        assertEquals(1, directInterfaces.size());
        // Same for the collection of all interfaces. Since the
        assertTrue(allInterfaces.contains(closeableType).isUnknown());
        assertTrue(allInterfaces.contains(autoCloseableType).isUnknown());
        assertFalse(allInterfaces.containsKnownInterface(closeableType));
        assertFalse(allInterfaces.containsKnownInterface(autoCloseableType));
        assertEquals(2, allInterfaces.size());
      }
    }

    ClassTypeElement scannerTypeElement = makeTypeElement(appView, scannerType);
    {
      // Scanner implements Closable and Iterator on all APIs.
      InterfaceCollection directInterfaces = scannerTypeElement.getInterfaces();
      assertTrue(directInterfaces.containsKnownInterface(closeableType));
      assertEquals(2, directInterfaces.size());

      // Joining a type of known with a type of unknown should still be unknown.
      ClassTypeElement joinLeft1 =
          scannerTypeElement.join(zipFileTypeElement, appView).asClassType();
      ClassTypeElement joinRight1 =
          zipFileTypeElement.join(scannerTypeElement, appView).asClassType();
      if (zipFileHasCloseable()) {
        assertTrue(joinLeft1.getInterfaces().contains(closeableType).isTrue());
        assertTrue(joinRight1.getInterfaces().contains(closeableType).isTrue());
      } else {
        assertTrue(joinLeft1.getInterfaces().contains(closeableType).isUnknown());
        assertTrue(joinRight1.getInterfaces().contains(closeableType).isUnknown());
      }
    }

    // Custom class derived from JarFile and Channel, thus it must implement closable.
    ClassTypeElement myJarFileScannerTypeElement = makeTypeElement(appView, myJarFileChannel);

    // Joining with Scanner will retain it as always Closeable.
    ClassTypeElement joinWithScanner =
        myJarFileScannerTypeElement.join(scannerTypeElement, appView).asClassType();
    assertTrue(joinWithScanner.getInterfaces().contains(closeableType).isTrue());

    // Joining with ZipFile will loose the assurance that it is Closeable.
    ClassTypeElement joinWithZipFile =
        myJarFileScannerTypeElement.join(zipFileTypeElement, appView).asClassType();
    assertTrue(joinWithZipFile.getInterfaces().contains(closeableType).isPossiblyTrue());
    assertEquals(
        zipFileHasCloseable(), joinWithZipFile.getInterfaces().contains(closeableType).isTrue());
  }

  private boolean zipFileHasCloseable() {
    return parameters.getApiLevel().isGreaterThanOrEqualTo(AndroidApiLevel.K);
  }

  private static ClassTypeElement makeTypeElement(
      AppView<AppInfoWithClassHierarchy> appView, DexType type) {
    return ClassTypeElement.create(type, Nullability.maybeNull(), appView);
  }

  static class MyJarFileScanner extends JarFile implements Channel {

    public MyJarFileScanner(String name) throws IOException {
      super(name);
    }

    @Override
    public boolean isOpen() {
      return false;
    }
  }

  static class TestClass {

    public static void foo(Object o) throws Exception {
      if (o instanceof AutoCloseable) {
        System.out.println("Is an AutoCloseable");
        ((AutoCloseable) o).close();
      } else {
        System.out.println("Not an AutoCloseable");
      }
    }

    public static void main(String[] args) throws Exception {
      foo(new JarFile(args[0]));
    }
  }
}
