/*
 * Copyright 2012-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.event.BuckEventBusFactory;
import com.facebook.buck.rules.BuildDependencies;
import com.facebook.buck.step.ExecutionContext;
import com.facebook.buck.testutil.TestConsole;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.base.Function;
import com.google.common.base.Functions;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import org.easymock.EasyMockSupport;
import org.junit.Test;

import java.io.File;

public class DependencyCheckingJavacStepTest extends EasyMockSupport {

  @Test
  public void testFindFailedImports() throws Exception {
    String lineSeperator = System.getProperty("line.separator");

    String stderrOutput = Joiner.on(lineSeperator).join(ImmutableList.of(
        "java/com/foo/bar.java:5: package javax.annotation.concurrent does not exist",
        "java/com/foo/bar.java:99: error: cannot access com.facebook.Raz",
        "java/com/foo/bar.java:142: cannot find symbol: class ImmutableSet",
        "java/com/foo/bar.java:999: you are a clown"));

    ImmutableSet<String> missingImports =
        DependencyCheckingJavacStep.findFailedImports(stderrOutput);
    assertEquals(
        ImmutableSet.of("javax.annotation.concurrent", "com.facebook.Raz", "ImmutableSet"),
        missingImports);
  }

  @Test
  public void testJavacCommand() {
    ExecutionContext context = ExecutionContext.builder()
        .setProjectFilesystem(new ProjectFilesystem(new File(".")) {
          @Override
          public Function<String, String> getPathRelativizer() {
            return Functions.identity();
          }
        })
        .setConsole(new TestConsole())
        .setEventBus(BuckEventBusFactory.newInstance()).build();

    DependencyCheckingJavacStep firstOrder = createTestStep(BuildDependencies.FIRST_ORDER_ONLY);
    DependencyCheckingJavacStep warn = createTestStep(BuildDependencies.WARN_ON_TRANSITIVE);
    DependencyCheckingJavacStep transitive = createTestStep(BuildDependencies.TRANSITIVE);

    assertEquals("javac -target 6 -source 6 -g -d . -classpath foo.jar foobar.java",
        firstOrder.getDescription(context));
    assertEquals("javac -target 6 -source 6 -g -d . -classpath foo.jar foobar.java",
        warn.getDescription(context));
    assertEquals("javac -target 6 -source 6 -g -d . -classpath bar.jar" + File.pathSeparator +
        "foo.jar foobar.java",
        transitive.getDescription(context));
  }

  private DependencyCheckingJavacStep createTestStep(BuildDependencies buildDependencies) {
    return new DependencyCheckingJavacStep(
          /* outputDirectory */ ".",
          /* javaSourceFilePaths */ ImmutableSet.of("foobar.java"),
          /* transitiveClasspathEntries */ ImmutableSet.of("bar.jar", "foo.jar"),
          /* declaredClasspathEntries */ ImmutableSet.of("foo.jar"),
          /* JavacOptions */ JavacOptions.DEFAULTS,
          /* pathToOutputAbiFile */ Optional.<String>absent(),
          /* invokingRule */ Optional.<String>absent(),
          /* buildDependencies */ buildDependencies,
          /* suggestBuildRules */ Optional.<DependencyCheckingJavacStep.SuggestBuildRules>absent());
  }
}
