// Copyright 2015 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.idlclass;

import static com.google.common.truth.Truth.assertThat;

import com.google.common.collect.Sets;
import com.google.devtools.build.buildjar.proto.JavaCompilation.CompilationUnit;
import com.google.devtools.build.buildjar.proto.JavaCompilation.Manifest;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

/** {@link IdlClass} test */
@RunWith(JUnit4.class)
public class IdlClassTest {

  static final Manifest MANIFEST =
      Manifest.newBuilder()
          .addCompilationUnit(
              CompilationUnit.newBuilder()
                  .setPath("c/g/Foo.java")
                  .setPkg("c.g")
                  .addTopLevel("Foo")
                  .addTopLevel("Bar"))
          .addCompilationUnit(
              CompilationUnit.newBuilder()
                  .setPath("c/g/Bar.java")
                  .setPkg("c.g")
                  .addTopLevel("Bar")
                  .addTopLevel("Bar2"))
          .addCompilationUnit(
              CompilationUnit.newBuilder()
                  // default package
                  .setPath("wrong/source/dir/Baz.java")
                  .addTopLevel("Baz"))
          .build();

  @Rule public TemporaryFolder tempFolder = new TemporaryFolder();

  @Test
  public void generatedPrefixes() {
    Set<Path> idlSources =
        Sets.newHashSet(Paths.get("c/g/Bar.java"), Paths.get("wrong/source/dir/Baz.java"));
    assertThat(IdlClass.getIdlPrefixes(MANIFEST, idlSources))
        .containsExactly("c/g/Bar", "c/g/Bar2", "Baz");
  }

  @Test
  public void idlClass() throws IOException {
    File classJar = tempFolder.newFile("lib.jar");
    File manifestProto = tempFolder.newFile("lib.manifest");
    File tempDir = tempFolder.newFolder("temp_files");
    File outputClassJar = tempFolder.newFile("lib-idl.jar");
    File outputSourceJar = tempFolder.newFile("lib-idl-src.jar");

    List<String> classes =
        Arrays.asList(
            "Baz.class",
            "Baz$0.class",
            "Baz$1.class",
            "c/g/Foo.class",
            "c/g/Foo$0.class",
            "c/g/Foo$Inner.class",
            "c/g/Foo$Inner$InnerMost.class",
            "c/g/Bar.class",
            "c/g/Bar2.class",
            "c/g/Bar$Inner.class",
            "c/g/Bar2$Inner.class");

    try (OutputStream os = new FileOutputStream(classJar);
        ZipOutputStream zos = new ZipOutputStream(os)) {
      for (String path : classes) {
        zos.putNextEntry(new ZipEntry(path));
      }
    }

    tempFolder.newFolder("c");
    tempFolder.newFolder("c", "g");
    tempFolder.newFolder("wrong");
    tempFolder.newFolder("wrong", "source");
    tempFolder.newFolder("wrong", "source", "dir");
    for (String file : Arrays.asList("c/g/Foo.java", "c/g/Bar.java", "wrong/source/dir/Baz.java")) {
      tempFolder.newFile(file);
    }

    try (OutputStream os = new FileOutputStream(manifestProto)) {
      MANIFEST.writeTo(os);
    }

    IdlClass.main(
        new String[]{
            "--manifest_proto",
            manifestProto.toString(),
            "--class_jar",
            classJar.toString(),
            "--output_class_jar",
            outputClassJar.toString(),
            "--output_source_jar",
            outputSourceJar.toString(),
            "--temp_dir",
            tempDir.toString(),
            "--idl_source_base_dir",
            tempFolder.getRoot().getPath(),
            "c/g/Bar.java",
            "wrong/source/dir/Baz.java"
        });

    List<String> classJarEntries = getJarEntries(outputClassJar);
    assertThat(classJarEntries)
        .containsExactly(
            "c/g/Bar.class",
            "c/g/Bar$Inner.class",
            "c/g/Bar2.class",
            "c/g/Bar2$Inner.class",
            "Baz.class",
            "Baz$0.class",
            "Baz$1.class");

    List<String> sourceJarEntries = getJarEntries(outputSourceJar);
    assertThat(sourceJarEntries)
        .containsExactly(
            "c/g/Bar.java",
            "Baz.java");
  }

  private List<String> getJarEntries(File outputJar) throws IOException {
    List<String> jarEntries = new ArrayList<>();
    try (ZipFile zf = new ZipFile(outputJar)) {
      Enumeration<? extends ZipEntry> entries = zf.entries();
      while (entries.hasMoreElements()) {
        String name = entries.nextElement().getName();
        if (name.endsWith("/") || name.equals("META-INF/MANIFEST.MF")) {
          continue;
        }
        jarEntries.add(name);
      }
    }
    return jarEntries;
  }
}
