/*
 * Copyright 2014-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.apple;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.hasItem;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import com.facebook.buck.apple.xcode.XCScheme;
import com.facebook.buck.apple.xcode.xcodeproj.PBXTarget;
import com.facebook.buck.io.ProjectFilesystem;
import com.facebook.buck.model.BuildTarget;
import com.facebook.buck.rules.TargetGraph;
import com.facebook.buck.rules.TargetNode;
import com.facebook.buck.rules.coercer.Either;
import com.facebook.buck.testutil.FakeProjectFilesystem;
import com.facebook.buck.testutil.TargetGraphFactory;
import com.facebook.buck.timing.SettableFakeClock;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Maps;

import org.hamcrest.FeatureMatcher;
import org.hamcrest.Matcher;
import org.hamcrest.core.AllOf;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;

public class WorkspaceAndProjectGeneratorTest {

  private ProjectFilesystem projectFilesystem;

  private TargetGraph targetGraph;
  private TargetNode<XcodeWorkspaceConfigDescription.Arg> workspaceNode;

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Before
  public void setUp() throws IOException {
    projectFilesystem = new FakeProjectFilesystem(new SettableFakeClock(0, 0));

    // Add support files needed by project generation to fake filesystem.
    projectFilesystem.writeContentsToPath(
        "",
        Paths.get(ProjectGenerator.PATH_TO_ASSET_CATALOG_BUILD_PHASE_SCRIPT));
    projectFilesystem.writeContentsToPath(
        "",
        Paths.get(ProjectGenerator.PATH_TO_ASSET_CATALOG_COMPILER));

    setUpWorkspaceAndProjects();
  }

  private void setUpWorkspaceAndProjects() {
    // Create the following dep tree:
    // FooBin -has-test-> FooBinTest
    // |
    // V
    // FooLib -has-test-> FooLibTest
    // |                  |
    // V                  V
    // BarLib             BazLib -has-test-> BazLibTest
    // ^
    // |
    // QuxBin
    //
    //
    // FooBin and BazLib use "tests" to specify their tests while FooLibTest uses source_under_test
    // to specify that it is a test of FooLib.
    //
    // Calling generate on FooBin should pull in everything except BazLibTest and QuxBin

    BuildTarget bazTestTarget = BuildTarget.builder("//baz", "xctest").build();
    BuildTarget fooBinTestTarget = BuildTarget.builder("//foo", "bin-xctest").build();
    BuildTarget fooTestTarget = BuildTarget.builder("//foo", "lib-xctest").build();

    BuildTarget barLibTarget = BuildTarget.builder("//bar", "lib").build();
    TargetNode<?> barLibNode = AppleLibraryBuilder
        .createBuilder(barLibTarget)
        .build();

    BuildTarget fooLibTarget = BuildTarget.builder("//foo", "lib").build();
    TargetNode<?> fooLibNode = AppleLibraryBuilder
        .createBuilder(fooLibTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(barLibTarget)))
        .setTests(Optional.of(ImmutableSortedSet.of(fooTestTarget)))
        .build();

    BuildTarget fooBinBinaryTarget = BuildTarget.builder("//foo", "binbinary").build();
    TargetNode<?> fooBinBinaryNode = AppleBinaryBuilder
        .createBuilder(fooBinBinaryTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(fooLibTarget)))
        .build();

    BuildTarget fooBinTarget = BuildTarget.builder("//foo", "bin").build();
    TargetNode<?> fooBinNode = AppleBundleBuilder
        .createBuilder(fooBinTarget)
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.APP))
        .setBinary(fooBinBinaryTarget)
        .setTests(Optional.of(ImmutableSortedSet.of(fooBinTestTarget)))
        .build();

    BuildTarget bazLibTarget = BuildTarget.builder("//baz", "lib").build();
    TargetNode<?> bazLibNode = AppleLibraryBuilder
        .createBuilder(bazLibTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(fooLibTarget)))
        .setTests(Optional.of(ImmutableSortedSet.of(bazTestTarget)))
        .build();

    TargetNode<?> bazTestNode = AppleTestBuilder
        .createBuilder(bazTestTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(bazLibTarget)))
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .build();

    TargetNode<?> fooTestNode = AppleTestBuilder
        .createBuilder(fooTestTarget)
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .setDeps(Optional.of(ImmutableSortedSet.of(bazLibTarget)))
        .build();

    TargetNode<?> fooBinTestNode = AppleTestBuilder
        .createBuilder(fooBinTestTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(fooBinTarget)))
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .build();

    BuildTarget quxBinTarget = BuildTarget.builder("//qux", "bin").build();
    TargetNode<?> quxBinNode = AppleBinaryBuilder
        .createBuilder(quxBinTarget)
        .setDeps(Optional.of(ImmutableSortedSet.of(barLibTarget)))
        .build();

    BuildTarget workspaceTarget = BuildTarget.builder("//foo", "workspace").build();
    workspaceNode = XcodeWorkspaceConfigBuilder
        .createBuilder(workspaceTarget)
        .setWorkspaceName(Optional.of("workspace"))
        .setSrcTarget(Optional.of(fooBinTarget))
        .build();

    targetGraph = TargetGraphFactory.newInstance(
        barLibNode,
        fooLibNode,
        fooBinBinaryNode,
        fooBinNode,
        bazLibNode,
        bazTestNode,
        fooTestNode,
        fooBinTestNode,
        quxBinNode,
        workspaceNode);
  }

  @Test
  public void workspaceAndProjectsShouldDiscoverDependenciesAndTests() throws IOException {
    WorkspaceAndProjectGenerator generator = new WorkspaceAndProjectGenerator(
        projectFilesystem,
        targetGraph,
        workspaceNode,
        ImmutableSet.of(ProjectGenerator.Option.INCLUDE_TESTS),
        false /* combinedProject */,
        "BUCK");
    Map<Path, ProjectGenerator> projectGenerators = new HashMap<>();
    generator.generateWorkspaceAndDependentProjects(projectGenerators);

    ProjectGenerator fooProjectGenerator =
        projectGenerators.get(Paths.get("foo"));
    ProjectGenerator barProjectGenerator =
        projectGenerators.get(Paths.get("bar"));
    ProjectGenerator bazProjectGenerator =
        projectGenerators.get(Paths.get("baz"));
    ProjectGenerator quxProjectGenerator =
        projectGenerators.get(Paths.get("qux"));

    assertNull(
        "The Qux project should not be generated at all",
        quxProjectGenerator);

    assertNotNull(
        "The Foo project should have been generated",
        fooProjectGenerator);

    assertNotNull(
        "The Bar project should have been generated",
        barProjectGenerator);

    assertNotNull(
        "The Baz project should have been generated",
        bazProjectGenerator);

    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:bin");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:lib");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:bin-xctest");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:lib-xctest");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        barProjectGenerator.getGeneratedProject(),
        "//bar:lib");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        bazProjectGenerator.getGeneratedProject(),
        "//baz:lib");
  }

  @Test
  public void combinedProjectShouldDiscoverDependenciesAndTests() throws IOException {
    WorkspaceAndProjectGenerator generator = new WorkspaceAndProjectGenerator(
        projectFilesystem,
        targetGraph,
        workspaceNode,
        ImmutableSet.of(ProjectGenerator.Option.INCLUDE_TESTS),
        true /* combinedProject */,
        "BUCK");
    Map<Path, ProjectGenerator> projectGenerators = new HashMap<>();
    generator.generateWorkspaceAndDependentProjects(projectGenerators);

    assertTrue(
        "Combined project generation should not populate the project generators map",
        projectGenerators.isEmpty());

    Optional<ProjectGenerator> projectGeneratorOptional = generator.getCombinedProjectGenerator();
    assertTrue(
        "Combined project generator should be present",
        projectGeneratorOptional.isPresent());
    ProjectGenerator projectGenerator = projectGeneratorOptional.get();

    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//foo:bin");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//foo:lib");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//foo:bin-xctest");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//foo:lib-xctest");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//bar:lib");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerator.getGeneratedProject(),
        "//baz:lib");
  }

  @Test
  public void workspaceAndProjectsWithoutTests() throws IOException {
    WorkspaceAndProjectGenerator generator = new WorkspaceAndProjectGenerator(
        projectFilesystem,
        targetGraph,
        workspaceNode,
        ImmutableSet.<ProjectGenerator.Option>of(),
        false /* combinedProject */,
        "BUCK");
    Map<Path, ProjectGenerator> projectGenerators = new HashMap<>();
    generator.generateWorkspaceAndDependentProjects(projectGenerators);

    ProjectGenerator fooProjectGenerator =
        projectGenerators.get(Paths.get("foo"));
    ProjectGenerator barProjectGenerator =
        projectGenerators.get(Paths.get("bar"));
    ProjectGenerator bazProjectGenerator =
        projectGenerators.get(Paths.get("baz"));
    ProjectGenerator quxProjectGenerator =
        projectGenerators.get(Paths.get("qux"));

    assertNull(
        "The Qux project should not be generated at all",
        quxProjectGenerator);

    assertNull(
        "The Baz project should not be generated at all",
        bazProjectGenerator);

    assertNotNull(
        "The Foo project should have been generated",
        fooProjectGenerator);

    assertNotNull(
        "The Bar project should have been generated",
        barProjectGenerator);

    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:bin");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        fooProjectGenerator.getGeneratedProject(),
        "//foo:lib");
    ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        barProjectGenerator.getGeneratedProject(),
        "//bar:lib");
  }

  @Test
  public void combinedTestBundle() throws IOException {
    TargetNode<AppleTestDescription.Arg> combinableTest1 = AppleTestBuilder
        .createBuilder(BuildTarget.builder("//foo", "combinableTest1").build())
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .setCanGroup(Optional.of(true))
        .build();
    TargetNode<AppleTestDescription.Arg> combinableTest2 = AppleTestBuilder
        .createBuilder(BuildTarget.builder("//bar", "combinableTest2").build())
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .setCanGroup(Optional.of(true))
        .build();
    TargetNode<AppleTestDescription.Arg> testMarkedUncombinable = AppleTestBuilder
        .createBuilder(BuildTarget.builder("//foo", "testMarkedUncombinable").build())
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.XCTEST))
        .setCanGroup(Optional.of(false))
        .build();
    TargetNode<AppleTestDescription.Arg> anotherTest = AppleTestBuilder
        .createBuilder(BuildTarget.builder("//foo", "anotherTest").build())
        .setExtension(Either.<AppleBundleExtension, String>ofLeft(AppleBundleExtension.OCTEST))
        .setCanGroup(Optional.of(true))
        .build();
    TargetNode<AppleNativeTargetDescriptionArg> library = AppleLibraryBuilder
        .createBuilder(BuildTarget.builder("//foo", "lib").build())
        .setTests(
            Optional.of(
                ImmutableSortedSet.of(
                    combinableTest1.getBuildTarget(),
                    combinableTest2.getBuildTarget(),
                    testMarkedUncombinable.getBuildTarget(),
                    anotherTest.getBuildTarget())))
        .build();
    TargetNode<XcodeWorkspaceConfigDescription.Arg> workspace = XcodeWorkspaceConfigBuilder
        .createBuilder(BuildTarget.builder("//foo", "workspace").build())
        .setSrcTarget(Optional.of(library.getBuildTarget()))
        .setWorkspaceName(Optional.of("workspace"))
        .build();

    TargetGraph targetGraph =
        TargetGraphFactory.newInstance(
            library,
            combinableTest1,
            combinableTest2,
            testMarkedUncombinable,
            anotherTest,
            workspace);

    WorkspaceAndProjectGenerator generator = new WorkspaceAndProjectGenerator(
        projectFilesystem,
        targetGraph,
        workspace,
        ImmutableSet.of(ProjectGenerator.Option.INCLUDE_TESTS),
        false,
        "BUCK");
    generator.setGroupableTests(AppleBuildRules.filterGroupableTests(targetGraph.getNodes()));
    Map<Path, ProjectGenerator> projectGenerators = Maps.newHashMap();
    generator.generateWorkspaceAndDependentProjects(projectGenerators);

    // Tests should become libraries
    PBXTarget combinableTestTarget1 = ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerators.get(Paths.get("foo")).getGeneratedProject(),
        "//foo:combinableTest1");
    assertEquals(
        "Test in the bundle should be built as a static library.",
        PBXTarget.ProductType.STATIC_LIBRARY,
        combinableTestTarget1.getProductType());

    PBXTarget combinableTestTarget2 = ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerators.get(Paths.get("bar")).getGeneratedProject(),
        "//bar:combinableTest2");
    assertEquals(
        "Other test in the bundle should be built as a static library.",
        PBXTarget.ProductType.STATIC_LIBRARY,
        combinableTestTarget2.getProductType());

    // Test not bundled with any others should retain behavior.
    PBXTarget notCombinedTest = ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerators.get(Paths.get("foo")).getGeneratedProject(),
        "//foo:anotherTest");
    assertEquals(
        "Test that is not combined with other tests should also generate a test bundle.",
        PBXTarget.ProductType.STATIC_LIBRARY,
        notCombinedTest.getProductType());

    // Test not bundled with any others should retain behavior.
    PBXTarget uncombinableTest = ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        projectGenerators.get(Paths.get("foo")).getGeneratedProject(),
        "//foo:testMarkedUncombinable");
    assertEquals(
        "Test marked uncombinable should not be combined",
        PBXTarget.ProductType.UNIT_TEST,
        uncombinableTest.getProductType());

    // Combined test project should be generated with a combined test bundle.
    PBXTarget combinedTestBundle = ProjectGeneratorTestUtils.assertTargetExistsAndReturnTarget(
        generator.getCombinedTestsProjectGenerator().get().getGeneratedProject(),
        "_BuckCombinedTest-xctest-0");
    assertEquals(
        "Combined test project target should be test bundle.",
        PBXTarget.ProductType.UNIT_TEST,
        combinedTestBundle.getProductType());

    // Scheme should contain generated test targets.
    XCScheme scheme = generator.getSchemeGenerator().get().getOutputScheme().get();
    XCScheme.TestAction testAction = scheme.getTestAction().get();
    assertThat(
        "Combined test target should be a testable",
        testAction.getTestables(),
        hasItem(testableWithName("_BuckCombinedTest-xctest-0")));
    assertThat(
        "Uncombined but groupable test should be a testable",
        testAction.getTestables(),
        hasItem(testableWithName("_BuckCombinedTest-octest-1")));
    assertThat(
        "Bundled test library is not a testable",
        testAction.getTestables(),
        not(hasItem(testableWithName("combinableTest1"))));

    XCScheme.BuildAction buildAction = scheme.getBuildAction().get();
    assertThat(
        "Bundled test library should be built for tests",
        buildAction.getBuildActionEntries(),
        hasItem(
            withNameAndBuildingFor(
                "combinableTest1",
                equalTo(XCScheme.BuildActionEntry.BuildFor.TEST_ONLY))));
    assertThat(
        "Combined test library should be built for tests",
        buildAction.getBuildActionEntries(),
        hasItem(
            withNameAndBuildingFor(
                "_BuckCombinedTest-xctest-0",
                equalTo(XCScheme.BuildActionEntry.BuildFor.TEST_ONLY))));
  }

  private Matcher<XCScheme.BuildActionEntry> buildActionEntryWithName(String name) {
    return new FeatureMatcher<XCScheme.BuildActionEntry, String>(
        equalTo(name), "BuildActionEntry named", "name") {
      @Override
      protected String featureValueOf(XCScheme.BuildActionEntry buildActionEntry) {
        return buildActionEntry.getBuildableReference().blueprintName;
      }
    };
  }

  private Matcher<XCScheme.TestableReference> testableWithName(String name) {
    return new FeatureMatcher<XCScheme.TestableReference, String>(
        equalTo(name), "TestableReference named", "name") {
      @Override
      protected String featureValueOf(XCScheme.TestableReference testableReference) {
        return testableReference.getBuildableReference().blueprintName;
      }
    };
  }
  private Matcher<XCScheme.BuildActionEntry> withNameAndBuildingFor(
      String name,
      Matcher<? super EnumSet<XCScheme.BuildActionEntry.BuildFor>> buildFor) {
    return AllOf.allOf(
        buildActionEntryWithName(name),
        new FeatureMatcher<
            XCScheme.BuildActionEntry,
            EnumSet<XCScheme.BuildActionEntry.BuildFor>>(buildFor, "Building for", "BuildFor") {
          @Override
          protected EnumSet<XCScheme.BuildActionEntry.BuildFor> featureValueOf(
              XCScheme.BuildActionEntry entry) {
            return entry.getBuildFor();
          }
        });
  }
}
