/*
 * Copyright 2016 Google Inc. 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.turbine.deps;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.common.truth.Truth.assertThat;
import static java.nio.charset.StandardCharsets.UTF_8;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.common.io.ByteStreams;
import com.google.turbine.bytecode.ClassFile;
import com.google.turbine.bytecode.ClassFile.InnerClass;
import com.google.turbine.bytecode.ClassReader;
import com.google.turbine.main.Main;
import com.google.turbine.options.TurbineOptions;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;

public abstract class AbstractTransitiveTest {

  protected abstract Path runTurbine(ImmutableList<Path> sources, ImmutableList<Path> classpath)
      throws IOException;

  protected static final ImmutableList<Path> BOOTCLASSPATH =
      ImmutableList.of(Paths.get(System.getProperty("java.home")).resolve("lib/rt.jar"));

  @Rule public final TemporaryFolder temporaryFolder = new TemporaryFolder();

  class SourceBuilder {
    private final Path lib;
    private final ImmutableList.Builder<Path> sources = ImmutableList.builder();

    SourceBuilder() throws IOException {
      lib = temporaryFolder.newFolder().toPath();
    }

    SourceBuilder addSourceLines(String name, String... lines) throws IOException {
      Path path = lib.resolve(name);
      Files.createDirectories(path.getParent());
      Files.write(path, Arrays.asList(lines), UTF_8);
      sources.add(path);
      return this;
    }

    ImmutableList<Path> build() {
      return sources.build();
    }
  }

  private Map<String, byte[]> readJar(Path libb) throws IOException {
    Map<String, byte[]> jarEntries = new LinkedHashMap<>();
    try (JarFile jf = new JarFile(libb.toFile())) {
      Enumeration<JarEntry> entries = jf.entries();
      while (entries.hasMoreElements()) {
        JarEntry je = entries.nextElement();
        jarEntries.put(je.getName(), ByteStreams.toByteArray(jf.getInputStream(je)));
      }
    }
    return jarEntries;
  }

  @Test
  public void transitive() throws Exception {
    Path liba =
        runTurbine(
            new SourceBuilder()
                .addSourceLines(
                    "a/A.java",
                    "package a;",
                    "import java.util.Map;",
                    "public class A {",
                    "  public @interface Anno {",
                    "    int x() default 42;",
                    "  }",
                    "  public static class Inner {}",
                    "  public static final int CONST = 42;",
                    "  public int mutable = 42;",
                    "  public Map.Entry<String, String> f(Map<String, String> m) {",
                    "    return m.entrySet().iterator().next();",
                    "  }",
                    "}")
                .build(),
            ImmutableList.of());

    Path libb =
        runTurbine(
            new SourceBuilder()
                .addSourceLines("b/B.java", "package b;", "public class B extends a.A {}")
                .build(),
            ImmutableList.of(liba));

    // libb repackages A, and any member types
    assertThat(readJar(libb).keySet())
        .containsExactly(
            "b/B.class",
            "META-INF/TRANSITIVE/a/A.class",
            "META-INF/TRANSITIVE/a/A$Anno.class",
            "META-INF/TRANSITIVE/a/A$Inner.class");

    ClassFile a = ClassReader.read(readJar(libb).get("META-INF/TRANSITIVE/a/A.class"));
    // methods and non-constant fields are removed
    assertThat(getOnlyElement(a.fields()).name()).isEqualTo("CONST");
    assertThat(a.methods()).isEmpty();
    assertThat(Iterables.transform(a.innerClasses(), InnerClass::innerClass))
        .containsExactly("a/A$Anno", "a/A$Inner");

    // annotation interface methods are preserved
    assertThat(ClassReader.read(readJar(libb).get("META-INF/TRANSITIVE/a/A$Anno.class")).methods())
        .hasSize(1);

    // A class that references members of the transitive supertype A by simple name
    // compiles cleanly against the repackaged version of A.
    // Explicitly use turbine; javac-turbine doesn't support direct-classpath compilations.

    Path libc = temporaryFolder.newFolder().toPath().resolve("out.jar");
    List<String> sources =
        new SourceBuilder()
            .addSourceLines(
                "c/C.java",
                "package c;",
                "public class C extends b.B {",
                "  @Anno(x = 2) static final Inner i; // a.A$Inner ",
                "  static final int X = CONST; // a.A#CONST",
                "}")
            .build()
            .stream()
            .map(Path::toString)
            .collect(toImmutableList());
    boolean ok =
        Main.compile(
            TurbineOptions.builder()
                .addSources(sources)
                .addClassPathEntries(
                    ImmutableList.of(libb).stream().map(Path::toString).collect(toImmutableList()))
                .addBootClassPathEntries(Iterables.transform(BOOTCLASSPATH, Path::toString))
                .setOutput(libc.toString())
                .build());
    assertThat(ok).isTrue();

    assertThat(readJar(libc).keySet())
        .containsExactly(
            "c/C.class",
            "META-INF/TRANSITIVE/b/B.class",
            "META-INF/TRANSITIVE/a/A.class",
            "META-INF/TRANSITIVE/a/A$Anno.class",
            "META-INF/TRANSITIVE/a/A$Inner.class");
  }

  @Test
  public void anonymous() throws Exception {
    Path liba = temporaryFolder.newFolder().toPath().resolve("out.jar");
    try (OutputStream os = Files.newOutputStream(liba);
        JarOutputStream jos = new JarOutputStream(os)) {
      {
        jos.putNextEntry(new JarEntry("a/A.class"));
        ClassWriter cw = new ClassWriter(0);
        cw.visit(52, Opcodes.ACC_SUPER | Opcodes.ACC_PUBLIC, "a/A", null, "java/lang/Object", null);
        cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        cw.visitInnerClass("a/A$1", "a/A", null, Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC);
        cw.visitInnerClass("a/A$I", "a/A", "I", Opcodes.ACC_STATIC);
        jos.write(cw.toByteArray());
      }
      {
        jos.putNextEntry(new JarEntry("a/A$1.class"));
        ClassWriter cw = new ClassWriter(0);
        cw.visit(
            52, Opcodes.ACC_SUPER | Opcodes.ACC_PUBLIC, "a/A$1", null, "java/lang/Object", null);
        cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        cw.visitInnerClass("a/A$1", "a/A", "I", Opcodes.ACC_STATIC | Opcodes.ACC_SYNTHETIC);
        jos.write(cw.toByteArray());
      }
      {
        jos.putNextEntry(new JarEntry("a/A$I.class"));
        ClassWriter cw = new ClassWriter(0);
        cw.visit(
            52, Opcodes.ACC_SUPER | Opcodes.ACC_PUBLIC, "a/A$I", null, "java/lang/Object", null);
        cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);
        cw.visitInnerClass("a/A$I", "a/A", "I", Opcodes.ACC_STATIC);
        jos.write(cw.toByteArray());
      }
    }
    Path libb =
        runTurbine(
            new SourceBuilder()
                .addSourceLines(
                    "b/B.java", //
                    "package b;",
                    "public class B extends a.A {}")
                .build(),
            ImmutableList.of(liba));

    // libb repackages A and any named member types
    assertThat(readJar(libb).keySet())
        .containsExactly(
            "b/B.class", "META-INF/TRANSITIVE/a/A.class", "META-INF/TRANSITIVE/a/A$I.class");
  }

  @Test
  public void childClass() throws Exception {
    Path liba =
        runTurbine(
            new SourceBuilder()
                .addSourceLines(
                    "a/S.java", //
                    "package a;",
                    "public class S {}")
                .addSourceLines(
                    "a/A.java", //
                    "package a;",
                    "public class A {",
                    "  public class I extends S {}",
                    "}")
                .build(),
            ImmutableList.of());

    Path libb =
        runTurbine(
            new SourceBuilder()
                .addSourceLines(
                    "b/B.java", //
                    "package b;",
                    "public class B extends a.A {",
                    "  class I extends a.A.I {",
                    "  }",
                    "}")
                .build(),
            ImmutableList.of(liba));

    assertThat(readJar(libb).keySet())
        .containsExactly(
            "b/B.class",
            "b/B$I.class",
            "META-INF/TRANSITIVE/a/A.class",
            "META-INF/TRANSITIVE/a/A$I.class",
            "META-INF/TRANSITIVE/a/S.class");
  }
}
