/*
 * Copyright 2013-present Facebook, Inc.
 *
 * 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.facebook.buck.java;

import static org.junit.Assert.assertEquals;

import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.TestExecutionContext;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.hash.HashCode;
import com.google.common.io.Files;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;

public class AccumulateClassNamesStepTest {

  private static final String SHA1_FOR_EMPTY_STRING = "da39a3ee5e6b4b0d3255bfef95601890afd80709";

  @Rule
  public TemporaryFolder tmp = new TemporaryFolder();

  @Test
  public void testExecuteAccumulateClassNamesStepOnJarFile() throws IOException {
    // Create a JAR file.
    String name = "example.jar";
    File jarFile = tmp.newFile(name);
    try (JarOutputStream out = new JarOutputStream(
        new BufferedOutputStream(
            new FileOutputStream(jarFile)))) {
      out.putNextEntry(new ZipEntry("com/example/Foo.class"));
      out.closeEntry();
      out.putNextEntry(new ZipEntry("com/example/Bar.class"));
      out.closeEntry();
      out.putNextEntry(new ZipEntry("com/example/not_a_class.png"));
      out.closeEntry();
      out.putNextEntry(new ZipEntry("com/example/subpackage/Baz.class"));
      out.closeEntry();
    }

    // Create the AccumulateClassNamesStep and execute it.
    AccumulateClassNamesStep accumulateClassNamesStep = new AccumulateClassNamesStep(
        Paths.get(name), Paths.get("output.txt"));
    ExecutionContext context = TestExecutionContext
        .newBuilder()
        .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot()))
        .build();
    accumulateClassNamesStep.execute(context);

    String contents = Files.toString(new File(tmp.getRoot(), "output.txt"), Charsets.UTF_8);
    String separator = AccumulateClassNamesStep.CLASS_NAME_HASH_CODE_SEPARATOR;
    assertEquals(
        "Verify that the contents are sorted alphabetically and ignore non-.class files.",
        Joiner.on('\n').join(
            "com/example/Bar" + separator + SHA1_FOR_EMPTY_STRING,
            "com/example/Foo" + separator + SHA1_FOR_EMPTY_STRING,
            "com/example/subpackage/Baz" + separator + SHA1_FOR_EMPTY_STRING) + '\n',
        contents);
    assertEquals(
        "get() should return the class name/hash mappings.",
        ImmutableSortedMap.of(
          "com/example/Bar", HashCode.fromString(SHA1_FOR_EMPTY_STRING),
          "com/example/Foo", HashCode.fromString(SHA1_FOR_EMPTY_STRING),
          "com/example/subpackage/Baz", HashCode.fromString(SHA1_FOR_EMPTY_STRING)
        ),
        accumulateClassNamesStep.get());
  }

  @Test
  public void testExecuteAccumulateClassNamesStepOnDirectory() throws IOException {
    // Create a directory.
    String name = "dir";
    tmp.newFolder(name);

    tmp.newFolder("dir/com");
    tmp.newFolder("dir/com/example");
    tmp.newFolder("dir/com/example/subpackage");

    tmp.newFile("dir/com/example/Foo.class");
    tmp.newFile("dir/com/example/Bar.class");
    tmp.newFile("dir/com/example/not_a_class.png");
    tmp.newFile("dir/com/example/subpackage/Baz.class");

    // Create the AccumulateClassNamesStep and execute it.
    AccumulateClassNamesStep accumulateClassNamesStep = new AccumulateClassNamesStep(
        Paths.get(name), Paths.get("output.txt"));
    ExecutionContext context = TestExecutionContext
        .newBuilder()
        .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot()))
        .build();
    accumulateClassNamesStep.execute(context);

    String contents = Files.toString(new File(tmp.getRoot(), "output.txt"), Charsets.UTF_8);
    String separator = AccumulateClassNamesStep.CLASS_NAME_HASH_CODE_SEPARATOR;
    assertEquals(
        "Verify that the contents are sorted alphabetically and ignore non-.class files.",
        Joiner.on('\n').join(
            "com/example/Bar" + separator + SHA1_FOR_EMPTY_STRING,
            "com/example/Foo" + separator + SHA1_FOR_EMPTY_STRING,
            "com/example/subpackage/Baz" + separator + SHA1_FOR_EMPTY_STRING) + '\n',
        contents);
    assertEquals(
        "get() should return the class name/hash mappings.",
        ImmutableSortedMap.of(
          "com/example/Bar", HashCode.fromString(SHA1_FOR_EMPTY_STRING),
          "com/example/Foo", HashCode.fromString(SHA1_FOR_EMPTY_STRING),
          "com/example/subpackage/Baz", HashCode.fromString(SHA1_FOR_EMPTY_STRING)
        ),
        accumulateClassNamesStep.get());
  }

  @Test(expected = NullPointerException.class)
  public void testGetClassesBeforeExecuteThrowsException() {
    AccumulateClassNamesStep accumulateClassNamesStep = new AccumulateClassNamesStep(
        Paths.get("pathToJarOrClassesDirectory"),
        Paths.get("whereClassNamesShouldBeWritten"));
    accumulateClassNamesStep.get();
  }
}
