// 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().getLevel();
    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]));
    }
  }
}
