/*
 * 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.BuckEventBus;
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(new BuckEventBus()).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: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());
  }
}
