/*
 * 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.parser;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.facebook.buck.java.DefaultJavaLibraryRule;
import com.facebook.buck.model.BuildFileTree;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.model.BuildTargetFactory;
import com.facebook.buck.rules.AbstractBuildRuleBuilder;
import com.facebook.buck.rules.BuildTargetSourcePath;
import com.facebook.buck.rules.FileSourcePath;
import com.facebook.buck.rules.SourcePath;
import com.facebook.buck.util.HumanReadableException;
import com.facebook.buck.util.ProjectFilesystem;
import com.google.common.io.Files;

import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.IOException;

public class BuildRuleFactoryParamsTest {

  @ClassRule public static TemporaryFolder folder = new TemporaryFolder();
  private static ProjectFilesystem filesystem;
  private BuildTargetParser parser;
  private BuildFileTree tree;

  @BeforeClass
  public static void layOutExampleProject() throws IOException {
    File root = folder.getRoot();
    filesystem = new ProjectFilesystem(root);

    File deepest = new File(root, "src/com/facebook/demo");
    assertTrue("Unable to create test project layout", deepest.mkdirs());

    File lacksBuildFile = new File(root, "src/com/facebook/nobuild");
    assertTrue("Unable to create test project layout", lacksBuildFile.mkdirs());

    // The files just need to exist. We never actually read their contents.
    Files.touch(new File(root, "src/com/facebook/BUCK"));
    Files.touch(new File(root, "src/com/facebook/A.java"));
    Files.touch(new File(root, "src/com/facebook/demo/BUCK"));
    Files.touch(new File(root, "src/com/facebook/demo/B.java"));
    Files.touch(new File(root, "src/com/facebook/nobuild/C.java"));
  }

  @AfterClass
  public static void deleteExampleProject() {
    folder.delete();
  }

  @Before
  public void prepareParser() throws IOException {
    parser = new BuildTargetParser(filesystem);
    tree = BuildFileTree.constructBuildFileTree(filesystem);
  }

  @Test
  public void testResolveFilePathRelativeToBuildFileDirectoryInRootDirectory() throws IOException {
    Files.touch(new File(filesystem.getProjectRoot(), "build.xml"));

    BuildTarget buildTarget = BuildTargetFactory.newInstance("//:wakizashi");
    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        buildTarget);

    assertEquals("build.xml",
        params.resolveFilePathRelativeToBuildFileDirectory("build.xml"));
  }

  @Test
  public void testResolveFilePathRelativeToBuildFileDirectoryInSubDirectory() {
    BuildTarget buildTarget = BuildTargetFactory.newInstance("//src/com/facebook:Main");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        buildTarget);
    assertEquals("src/com/facebook/A.java",
        params.resolveFilePathRelativeToBuildFileDirectory("A.java"));
  }

  @Test
  public void testShouldWarnIfPathsContainReferencesToParentDirectories() {
    BuildTarget buildTarget = BuildTargetFactory.newInstance("//src/com/facebook/demo:Main");
    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        buildTarget);
    // File exists, but is in a parent directory.
    try {
      params.resolveFilePathRelativeToBuildFileDirectory("../A.java");
      fail("Expected path to be rejected.");
    } catch (HumanReadableException e) {
      assertEquals("\"src/com/facebook/demo/../A.java\" in target " +
          "\"//src/com/facebook/demo:Main\" refers to a parent directory.",
          e.getMessage());
    }
  }

  @Test
  public void testShouldWarnWhenAFileCrossesABuckPackageBoundary() {
    BuildTargetFactory.newInstance("//src/com/facebook/demo:demo");
    BuildTarget buildTarget = BuildTargetFactory.newInstance("//src/com/facebook:boundary");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        buildTarget);
    try {
      // File exists, but crosses a buck package boundary.
      params.resolveFilePathRelativeToBuildFileDirectory("demo/B.java");
      fail("Expected path to be rejected as it crosses a buck package boundary");
    } catch (HumanReadableException e) {
      assertEquals("\"src/com/facebook/demo/B.java\" in target \"//src/com/facebook:boundary\" " +
          "crosses a buck package boundary. Find the nearest BUCK file in the directory " +
          "containing this file and refer to the rule referencing the desired file.",
          e.getMessage());
    }
  }

  @Test
  public void testShouldAllowChildPathsIfTargetBuildFileIsClosest() {
    BuildTarget buildTarget = BuildTargetFactory.newInstance("//src/com/facebook:boundary");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        buildTarget);
    // File exists, is in a subdir but does not cross a buck package boundary
    String relativePath = params.resolveFilePathRelativeToBuildFileDirectory("nobuild/C.java");
    assertEquals("src/com/facebook/nobuild/C.java", relativePath);
  }

  @Test
  public void testShouldResolveFilesAsFileSourcePaths() {
    BuildTarget target = BuildTargetFactory.newInstance("//src/com/facebook:Main");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        target);
    AbstractBuildRuleBuilder<?> builder = createMock(AbstractBuildRuleBuilder.class);
    replay(builder);

    SourcePath first = params.asSourcePath("A.java", builder);
    assertTrue(first instanceof FileSourcePath);
    assertEquals("src/com/facebook/A.java", first.asReference());

    verify(builder);
  }

  @Test
  public void testShouldResolveAFullyQualifiedTargetAsABuildTargetSourcePath() {
    BuildTarget target = BuildTargetFactory.newInstance("//src/com/facebook:Main");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        target);
    DefaultJavaLibraryRule.Builder builder = createMock(DefaultJavaLibraryRule.Builder.class);
    expect(builder.addDep(
        new BuildTarget(
            "//src/com/facebook",
            "A")
        )).andReturn(builder);
    replay(builder);

    SourcePath first = params.asSourcePath("//src/com/facebook:A", builder);
    assertTrue(first instanceof BuildTargetSourcePath);
    assertEquals("//src/com/facebook:A", first.asReference());

    verify(builder);
  }

  @Test
  public void testShouldThrowAnExceptionIfTheBuildTargetIsUnknown() {
    BuildTarget target = BuildTargetFactory.newInstance("//src/com/facebook:Main");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        target);
    AbstractBuildRuleBuilder<?> builder = createMock(AbstractBuildRuleBuilder.class);
    replay(builder);

    try {
      params.asSourcePath("//does/not:exist", builder);
      fail("Should not have succeeded");
    } catch (HumanReadableException e) {
      assertEquals(
          "Unable to find build target '//does/not:exist' while parsing definition " +
              "of //src/com/facebook:Main",
          e.getMessage());
    }

    verify(builder);
  }

  @Test
  public void testShouldResolveAShortTargetAsABuildTargetSourcePath() {
    BuildTarget target = BuildTargetFactory.newInstance("//src/com/facebook:Main");

    BuildRuleFactoryParams params = new BuildRuleFactoryParams(
        null /* instance */,
        filesystem,
        tree,
        parser,
        target);
    DefaultJavaLibraryRule.Builder builder = createMock(DefaultJavaLibraryRule.Builder.class);
    expect(builder.addDep(
        new BuildTarget(
            "//src/com/facebook",
            "works")
        )).andReturn(builder);
    replay(builder);

    SourcePath first = params.asSourcePath(":works", builder);
    assertTrue(first instanceof BuildTargetSourcePath);
    assertEquals("//src/com/facebook:works", first.asReference());

    verify(builder);
  }

}
