/*
 * 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.io.ProjectFilesystem;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.step.TestExecutionContext;
import com.google.common.base.Charsets;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
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(
        Optional.of(Paths.get(name)), Paths.get("output.txt"));
    ExecutionContext context = TestExecutionContext
        .newBuilder()
        .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot().toPath()))
        .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);
  }

  @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(
        Optional.of(Paths.get(name)), Paths.get("output.txt"));
    ExecutionContext context = TestExecutionContext
        .newBuilder()
        .setProjectFilesystem(new ProjectFilesystem(tmp.getRoot().toPath()))
        .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);
  }
}

@@ -4397,32 +4397,42 @@
 in(%0A            
+Paths.get(
 %22com/example/Bar
@@ -4424,32 +4424,33 @@
 com/example/Bar%22
+)
  + separator + S
@@ -4475,32 +4475,42 @@
 NG,%0A            
+Paths.get(
 %22com/example/Foo
@@ -4502,32 +4502,33 @@
 com/example/Foo%22
+)
  + separator + S
@@ -4553,32 +4553,42 @@
 NG,%0A            
+Paths.get(
 %22com/example/sub
@@ -4591,32 +4591,33 @@
 /subpackage/Baz%22
+)
  + separator + S

Fix `AccumulateClassNamesStepTest` on Windows