// Copyright 2017 The Bazel Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.devtools.build.android.desugar;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.truth.Truth.assertThat;
import static com.google.devtools.build.android.desugar.DefaultMethodClassFixer.InterfaceComparator.INSTANCE;

import com.google.common.collect.ImmutableList;
import com.google.common.io.Closer;
import com.google.devtools.build.android.desugar.Desugar.ThrowingClassLoader;
import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;

/** Unit Test for {@link DefaultMethodClassFixer} */
@RunWith(JUnit4.class)
public class DefaultMethodClassFixerTest {

  private ClassReaderFactory classpathReader;
  private ClassReaderFactory bootclassPath;
  private ClassLoader classLoader;
  private Closer closer;

  @Before
  public void setup() throws IOException {
    closer = Closer.create();
    CoreLibraryRewriter rewriter = new CoreLibraryRewriter("");

    IndexedInputs indexedInputs =
        toIndexedInputs(closer, System.getProperty("DefaultMethodClassFixerTest.input"));
    IndexedInputs indexedClasspath =
        toIndexedInputs(closer, System.getProperty("DefaultMethodClassFixerTest.classpath"));
    IndexedInputs indexedBootclasspath =
        toIndexedInputs(closer, System.getProperty("DefaultMethodClassFixerTest.bootclasspath"));

    bootclassPath = new ClassReaderFactory(indexedBootclasspath, rewriter);
    IndexedInputs indexedClasspathAndInputFiles = indexedClasspath.withParent(indexedInputs);
    classpathReader = new ClassReaderFactory(indexedClasspathAndInputFiles, rewriter);
    ClassLoader bootclassloader =
        new HeaderClassLoader(indexedBootclasspath, rewriter, new ThrowingClassLoader());
    classLoader = new HeaderClassLoader(indexedClasspathAndInputFiles, rewriter, bootclassloader);
  }

  @After
  public void teardown() throws IOException {
    closer.close();
  }

  private static IndexedInputs toIndexedInputs(Closer closer, String stringPathList)
      throws IOException {
    final List<Path> pathList = readPathListFromString(stringPathList);
    return new IndexedInputs(Desugar.toRegisteredInputFileProvider(closer, pathList));
  }

  private static List<Path> readPathListFromString(String pathList) {
    return Arrays.stream(checkNotNull(pathList).split(File.pathSeparator))
        .map(Paths::get)
        .collect(ImmutableList.toImmutableList());
  }

  private byte[] desugar(String classname) {
    ClassReader reader = classpathReader.readIfKnown(classname);
    return desugar(reader);
  }

  private byte[] desugar(ClassReader reader) {
    ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS);
    DefaultMethodClassFixer fixer =
        new DefaultMethodClassFixer(
            writer,
            classpathReader,
            DependencyCollector.NoWriteCollectors.FAIL_ON_MISSING,
            bootclassPath,
            classLoader);
    reader.accept(fixer, 0);
    return writer.toByteArray();
  }

  private byte[] desugar(byte[] classContent) {
    ClassReader reader = new ClassReader(classContent);
    return desugar(reader);
  }

  @Test
  public void testDesugaringDirectImplementation() {
    byte[] desugaredClass =
        desugar(
            ("com.google.devtools.build.android.desugar.testdata.java8."
                    + "DefaultInterfaceMethodWithStaticInitializer$TestInterfaceSetOne$C")
                .replace('.', '/'));
    checkClinitForDefaultInterfaceMethodWithStaticInitializerTestInterfaceSetOneC(desugaredClass);

    byte[] desugaredClassAgain = desugar(desugaredClass);
    checkClinitForDefaultInterfaceMethodWithStaticInitializerTestInterfaceSetOneC(
        desugaredClassAgain);

    desugaredClassAgain = desugar(desugaredClassAgain);
    checkClinitForDefaultInterfaceMethodWithStaticInitializerTestInterfaceSetOneC(
        desugar(desugaredClassAgain));
  }

  private void checkClinitForDefaultInterfaceMethodWithStaticInitializerTestInterfaceSetOneC(
      byte[] classContent) {
    ClassReader reader = new ClassReader(classContent);
    reader.accept(
        new ClassVisitor(Opcodes.ASM5) {

          class ClinitMethod extends MethodNode {

            public ClinitMethod(
                int access, String name, String desc, String signature, String[] exceptions) {
              super(Opcodes.ASM5, access, name, desc, signature, exceptions);
            }
          }

          private ClinitMethod clinit;

          @Override
          public MethodVisitor visitMethod(
              int access, String name, String desc, String signature, String[] exceptions) {
            if ("<clinit>".equals(name)) {
              assertThat(clinit).isNull();
              clinit = new ClinitMethod(access, name, desc, signature, exceptions);
              return clinit;
            }
            return super.visitMethod(access, name, desc, signature, exceptions);
          }

          @Override
          public void visitEnd() {
            assertThat(clinit).isNotNull();
            assertThat(clinit.instructions.size()).isEqualTo(3);
            AbstractInsnNode instruction = clinit.instructions.getFirst();
            {
              assertThat(instruction).isInstanceOf(MethodInsnNode.class);
              MethodInsnNode field = (MethodInsnNode) instruction;
              assertThat(field.owner)
                  .isEqualTo(
                      "com/google/devtools/build/android/desugar/testdata/java8/"
                          + "DefaultInterfaceMethodWithStaticInitializer"
                          + "$TestInterfaceSetOne$I1$$CC");
              assertThat(field.name)
                  .isEqualTo(InterfaceDesugaring.COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_NAME);
              assertThat(field.desc)
                  .isEqualTo(InterfaceDesugaring.COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_DESC);
            }
            {
              instruction = instruction.getNext();
              assertThat(instruction).isInstanceOf(MethodInsnNode.class);
              MethodInsnNode field = (MethodInsnNode) instruction;
              assertThat(field.owner)
                  .isEqualTo(
                      "com/google/devtools/build/android/desugar/testdata/java8/"
                          + "DefaultInterfaceMethodWithStaticInitializer"
                          + "$TestInterfaceSetOne$I2$$CC");
              assertThat(field.name)
                  .isEqualTo(InterfaceDesugaring.COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_NAME);
              assertThat(field.desc)
                  .isEqualTo(InterfaceDesugaring.COMPANION_METHOD_TO_TRIGGER_INTERFACE_CLINIT_DESC);
            }
            {
              instruction = instruction.getNext();
              assertThat(instruction).isInstanceOf(InsnNode.class);
              assertThat(instruction.getOpcode()).isEqualTo(Opcodes.RETURN);
            }
          }
        },
        0);
  }

  @Test
  public void testInterfaceComparator() {
    assertThat(INSTANCE.compare(Runnable.class, Runnable.class)).isEqualTo(0);
    assertThat(INSTANCE.compare(Runnable.class, MyRunnable1.class)).isEqualTo(1);
    assertThat(INSTANCE.compare(MyRunnable2.class, Runnable.class)).isEqualTo(-1);
    assertThat(INSTANCE.compare(MyRunnable3.class, Runnable.class)).isEqualTo(-1);
    assertThat(INSTANCE.compare(MyRunnable1.class, MyRunnable3.class)).isEqualTo(1);
    assertThat(INSTANCE.compare(MyRunnable3.class, MyRunnable2.class)).isEqualTo(-1);
    assertThat(INSTANCE.compare(MyRunnable2.class, MyRunnable1.class)).isGreaterThan(0);
    assertThat(INSTANCE.compare(Runnable.class, Serializable.class)).isGreaterThan(0);
    assertThat(INSTANCE.compare(Serializable.class, Runnable.class)).isLessThan(0);

    TreeSet<Class<?>> orderedSet = new TreeSet<>(INSTANCE);
    orderedSet.add(Serializable.class);
    orderedSet.add(Runnable.class);
    orderedSet.add(MyRunnable2.class);
    orderedSet.add(Callable.class);
    orderedSet.add(Serializable.class);
    orderedSet.add(MyRunnable1.class);
    orderedSet.add(MyRunnable3.class);
    assertThat(orderedSet)
        .containsExactly(
            MyRunnable3.class, // subtype before supertype(s)
            MyRunnable1.class,
            MyRunnable2.class,
            Serializable.class, // java... comes textually after com.google...
            Runnable.class,
            Callable.class)
        .inOrder();
  }

  private static interface MyRunnable1 extends Runnable {}

  private static interface MyRunnable2 extends Runnable {}

  private static interface MyRunnable3 extends MyRunnable1, MyRunnable2 {}
}
