/*
 * Copyright 2016 The Bazel Authors. All rights reserved.
 *
 * 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.google.idea.blaze.java.sync.source;

import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.fail;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.idea.blaze.base.BlazeTestCase;
import com.google.idea.blaze.base.async.executor.BlazeExecutor;
import com.google.idea.blaze.base.async.executor.MockBlazeExecutor;
import com.google.idea.blaze.base.ideinfo.ArtifactLocation;
import com.google.idea.blaze.base.ideinfo.TargetKey;
import com.google.idea.blaze.base.io.FileAttributeProvider;
import com.google.idea.blaze.base.io.InputStreamProvider;
import com.google.idea.blaze.base.model.primitives.ExecutionRootPath;
import com.google.idea.blaze.base.model.primitives.Label;
import com.google.idea.blaze.base.model.primitives.WorkspacePath;
import com.google.idea.blaze.base.model.primitives.WorkspaceRoot;
import com.google.idea.blaze.base.prefetch.MockPrefetchService;
import com.google.idea.blaze.base.prefetch.PrefetchService;
import com.google.idea.blaze.base.scope.BlazeContext;
import com.google.idea.blaze.base.scope.ErrorCollector;
import com.google.idea.blaze.base.scope.output.IssueOutput;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoder;
import com.google.idea.blaze.base.sync.workspace.ArtifactLocationDecoderImpl;
import com.google.idea.blaze.base.sync.workspace.BlazeRoots;
import com.google.idea.blaze.base.sync.workspace.WorkspacePathResolverImpl;
import com.google.idea.blaze.java.sync.model.BlazeContentEntry;
import com.google.idea.blaze.java.sync.model.BlazeSourceDirectory;
import com.google.idea.common.experiments.ExperimentService;
import com.google.idea.common.experiments.MockExperimentService;
import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass;
import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass.JavaSourcePackage;
import com.google.repackaged.devtools.build.lib.ideinfo.androidstudio.PackageManifestOuterClass.PackageManifest;
import com.intellij.util.containers.HashMap;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Test cases for {@link SourceDirectoryCalculator}. */
@RunWith(JUnit4.class)
public class SourceDirectoryCalculatorTest extends BlazeTestCase {

  private static final ImmutableMap<TargetKey, ArtifactLocation> NO_MANIFESTS = ImmutableMap.of();
  private static final Label LABEL = new Label("//fake:label");

  private MockInputStreamProvider mockInputStreamProvider;
  private SourceDirectoryCalculator sourceDirectoryCalculator;

  private BlazeContext context = new BlazeContext();
  private ErrorCollector issues = new ErrorCollector();
  private MockExperimentService experimentService;

  private WorkspaceRoot workspaceRoot = new WorkspaceRoot(new File("/root"));
  private ArtifactLocationDecoder decoder =
      (ArtifactLocationDecoder)
          artifactLocation -> new File("/root", artifactLocation.getRelativePath());

  @Override
  protected void initTest(
      @NotNull Container applicationServices, @NotNull Container projectServices) {
    super.initTest(applicationServices, projectServices);

    mockInputStreamProvider = new MockInputStreamProvider();
    applicationServices.register(InputStreamProvider.class, mockInputStreamProvider);
    applicationServices.register(JavaSourcePackageReader.class, new JavaSourcePackageReader());
    applicationServices.register(PackageManifestReader.class, new PackageManifestReader());
    applicationServices.register(FileAttributeProvider.class, new MockFileAttributeProvider());

    context.addOutputSink(IssueOutput.class, issues);
    sourceDirectoryCalculator = new SourceDirectoryCalculator();

    BlazeExecutor blazeExecutor = new MockBlazeExecutor();
    applicationServices.register(BlazeExecutor.class, blazeExecutor);

    experimentService = new MockExperimentService();
    applicationServices.register(ExperimentService.class, experimentService);

    applicationServices.register(PrefetchService.class, new MockPrefetchService());
  }

  @Test
  public void testWorkspacePathIsAddedWithoutSources() throws Exception {
    List<SourceArtifact> sourceArtifacts = ImmutableList.of();
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google/app")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google/app")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/app")
                        .setPackagePrefix("com.google.app")
                        .build())
                .build());
  }

  @Test
  public void testCalculatesPackageForSimpleCase() throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .build());
    issues.assertNoIssues();
  }

  @Test
  public void testHandlesSourceAtProjectRoot() throws Exception {
    mockInputStreamProvider.addFile("/root/Bla.java", "package com.google;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder().setRelativePath("Bla.java").setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("")),
            sourceArtifacts,
            NO_MANIFESTS);
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root")
                .addSource(
                    BlazeSourceDirectory.builder("/root").setPackagePrefix("com.google").build())
                .build());
    issues.assertNoIssues();
  }

  @Test
  public void testSourcesToSourceDirectories_testReturnsTest() throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_multipleMatchingPackagesAreMerged() throws Exception {
    mockInputStreamProvider
        .addFile("/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/Bla.java",
            "package com.google.subpackage;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .build());
  }

  @Test
  public void testMultipleDirectoriesAreMergedWithDirectoryRootAsWorkspaceRoot() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/idea/blaze/plugin/run/Run.java",
            "package com.google.idea.blaze.plugin.run;\n public class run {}")
        .addFile(
            "/root/java/com/google/idea/blaze/plugin/sync/Sync.java",
            "package com.google.idea.blaze.plugin.sync;\n public class Sync {}")
        .addFile(
            "/root/java/com/google/idea/blaze/plugin/Plugin.java",
            "package com.google.idea.blaze.plugin;\n public class Plugin {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/plugin/run/Run.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/plugin/sync/Sync.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/plugin/Plugin.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root")
                .addSource(BlazeSourceDirectory.builder("/root").setPackagePrefix("").build())
                .addSource(BlazeSourceDirectory.builder("/root/java").setPackagePrefix("").build())
                .build());
  }

  @Test
  public void testIncorrectPackageInMiddleOfTreeCausesMergePointHigherUp() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/idea/blaze/plugin/run/Run.java",
            "package com.google.idea.blaze.plugin.run;\n public class run {}")
        .addFile(
            "/root/java/com/google/idea/blaze/plugin/sync/Sync.java",
            "package com.google.idea.blaze.plugin.sync;\n public class Sync {}")
        .addFile(
            "/root/java/com/google/idea/blaze/Incorrect.java",
            "package com.google.idea.blaze.incorrect;\n public class Incorrect {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/plugin/run/Run.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/plugin/sync/Sync.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/idea/blaze/Incorrect.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root")
                .addSource(BlazeSourceDirectory.builder("/root").setPackagePrefix("").build())
                .addSource(BlazeSourceDirectory.builder("/root/java").setPackagePrefix("").build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/idea/blaze")
                        .setPackagePrefix("com.google.idea.blaze.incorrect")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/idea/blaze/plugin")
                        .setPackagePrefix("com.google.idea.blaze.plugin")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_multipleNonMatchingPackagesAreNotMerged()
      throws Exception {
    mockInputStreamProvider
        .addFile("/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/Bla.java",
            "package com.google.different;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/subpackage")
                        .setPackagePrefix("com.google.different")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_childMatchesPathButParentDoesnt() throws Exception {
    mockInputStreamProvider
        .addFile("/root/java/com/google/Bla.java", "package com.facebook;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/Bla.java",
            "package com.google.subpackage;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.facebook")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/subpackage")
                        .setPackagePrefix("com.google.subpackage")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_orderIsIrrelevant() throws Exception {
    mockInputStreamProvider
        .addFile("/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/Bla.java",
            "package com.google.different;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/subpackage")
                        .setPackagePrefix("com.google.different")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_packagesMatchPath() throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_packagesDoNotMatchPath() throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/google/Bla.java", "package com.facebook;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.facebook")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_completePackagePathMismatch() throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/org/foo/Bla.java", "package com.facebook;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/org/foo/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/org")),
            sourceArtifacts,
            NO_MANIFESTS);
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/org")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/org")
                        .setPackagePrefix("com.org")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/org/foo")
                        .setPackagePrefix("com.facebook")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_sourcesOutsideOfModuleGeneratesIssue()
      throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/facebook/Bla.java", "package com.facebook;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/facebook/Bla.java")
                        .setIsSource(true))
                .build());
    sourceDirectoryCalculator.calculateContentEntries(
        project,
        context,
        workspaceRoot,
        decoder,
        ImmutableList.of(new WorkspacePath("java/com/google")),
        sourceArtifacts,
        NO_MANIFESTS);

    issues.assertIssueContaining("Did not add");
  }

  @Test
  public void testSourcesToSourceDirectories_generatedSourcesOutsideOfModuleGeneratesNoIssue()
      throws Exception {
    mockInputStreamProvider.addFile(
        "/root/java/com/facebook/Bla.java", "package com.facebook;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/facebook/Bla.java")
                        .setIsSource(false))
                .build());
    sourceDirectoryCalculator.calculateContentEntries(
        project,
        context,
        workspaceRoot,
        decoder,
        ImmutableList.of(new WorkspacePath("java/com/google/my")),
        sourceArtifacts,
        NO_MANIFESTS);
    issues.assertNoIssues();
  }

  @Test
  public void testSourcesToSourceDirectories_missingPackageDeclaration() throws Exception {
    mockInputStreamProvider.addFile("/root/java/com/google/Bla.java", "public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build());
    sourceDirectoryCalculator.calculateContentEntries(
        project,
        context,
        workspaceRoot,
        decoder,
        ImmutableList.of(new WorkspacePath("java/com/google")),
        sourceArtifacts,
        NO_MANIFESTS);

    issues.assertIssueContaining("No package name string found");
  }

  @Test
  public void testCompetingPackageDeclarationPicksMajority() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/Foo.java", "package com.google.different;\n public class Foo {}")
        .addFile("/root/java/com/google/Bla.java", "package com.google;\n public class Bla {}")
        .addFile("/root/java/com/google/Bla2.java", "package com.google;\n public class Bla2 {}")
        .addFile("/root/java/com/google/Bla3.java", "package com.google;\n public class Bla3 {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla2.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla3.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Foo.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_packagesMatchPathButNotAtRoot() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/Bla.java", "package com.google.different;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/Bla.java",
            "package com.google.subpackage;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/subpackage/subsubpackage/Bla.java",
            "package com.google.subpackage.subsubpackage;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/subsubpackage/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google.different")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/subpackage")
                        .setPackagePrefix("com.google.subpackage")
                        .build())
                .build());
  }

  @Test
  public void testSourcesToSourceDirectories_multipleSubdirectoriesAreNotMerged() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/package0/Bla.java",
            "package com.google.packagewrong0;\n public class Bla {}")
        .addFile(
            "/root/java/com/google/package1/Bla.java",
            "package com.google.packagewrong1;\n public class Bla {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/package0/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/package1/Bla.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/package0")
                        .setPackagePrefix("com.google.packagewrong0")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/package1")
                        .setPackagePrefix("com.google.packagewrong1")
                        .build())
                .build());
  }

  @Test
  public void testLowestDirectoryIsPrioritised() throws Exception {
    mockInputStreamProvider
        .addFile(
            "/root/java/com/google/android/chimera/internal/Preconditions.java",
            "package com.google.android.chimera.container.internal;\n "
                + "public class Preconditions {}")
        .addFile(
            "/root/java/com/google/android/chimera/container/FileApkUtils.java",
            "package com.google.android.chimera.container;\n public class FileApkUtils {}");
    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath(
                            "java/com/google/android/chimera/internal/Preconditions.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath(
                            "java/com/google/android/chimera/container/FileApkUtils.java")
                        .setIsSource(true))
                .build());
    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            decoder,
            ImmutableList.of(new WorkspacePath("java/com/google/android")),
            sourceArtifacts,
            NO_MANIFESTS);
    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google/android")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/android")
                        .setPackagePrefix("com.google.android")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/android/chimera/internal")
                        .setPackagePrefix("com.google.android.chimera.container.internal")
                        .build())
                .build());
  }

  @Test
  public void testNewFormatManifest() throws Exception {
    setNewFormatPackageManifest(
        "/root/java/com/test.manifest",
        ImmutableList.of(
            PackageManifestOuterClass.ArtifactLocation.newBuilder()
                .setRelativePath("java/com/google/Bla.java")
                .setIsSource(true)
                .build()),
        ImmutableList.of("com.google"));
    ImmutableMap<TargetKey, ArtifactLocation> manifests =
        ImmutableMap.<TargetKey, ArtifactLocation>builder()
            .put(
                TargetKey.forPlainTarget(LABEL),
                ArtifactLocation.builder()
                    .setRelativePath("java/com/test.manifest")
                    .setIsSource(true)
                    .build())
            .build();
    Map<TargetKey, Map<ArtifactLocation, String>> manifestMap =
        readPackageManifestFiles(manifests, getDecoder("/root"));

    assertThat(manifestMap.get(TargetKey.forPlainTarget(LABEL)))
        .containsEntry(
            ArtifactLocation.builder()
                .setRelativePath("java/com/google/Bla.java")
                .setIsSource(true)
                .build(),
            "com.google");
  }

  @Test
  public void testManifestSingleFile() throws Exception {
    setPackageManifest(
        "/root/java/com/test.manifest",
        ImmutableList.of("java/com/google/Bla.java"),
        ImmutableList.of("com.google"));
    ImmutableMap<TargetKey, ArtifactLocation> manifests =
        ImmutableMap.<TargetKey, ArtifactLocation>builder()
            .put(
                TargetKey.forPlainTarget(LABEL),
                ArtifactLocation.builder()
                    .setRelativePath("java/com/test.manifest")
                    .setIsSource(true)
                    .build())
            .build();
    Map<TargetKey, Map<ArtifactLocation, String>> manifestMap =
        readPackageManifestFiles(manifests, getDecoder("/root"));

    assertThat(manifestMap.get(TargetKey.forPlainTarget(LABEL)))
        .containsEntry(
            ArtifactLocation.builder()
                .setRelativePath("java/com/google/Bla.java")
                .setIsSource(true)
                .build(),
            "com.google");
  }

  @Test
  public void testManifestRepeatedSources() throws Exception {
    setPackageManifest(
        "/root/java/com/test.manifest",
        ImmutableList.of("java/com/google/Bla.java", "java/com/google/Foo.java"),
        ImmutableList.of("com.google", "com.google.subpackage"));
    setPackageManifest(
        "/root/java/com/test2.manifest",
        ImmutableList.of("java/com/google/Bla.java", "java/com/google/other/Temp.java"),
        ImmutableList.of("com.google", "com.google.other"));
    ImmutableMap<TargetKey, ArtifactLocation> manifests =
        ImmutableMap.<TargetKey, ArtifactLocation>builder()
            .put(
                TargetKey.forPlainTarget(new Label("//a:a")),
                ArtifactLocation.builder()
                    .setRelativePath("java/com/test.manifest")
                    .setIsSource(true)
                    .build())
            .put(
                TargetKey.forPlainTarget(new Label("//b:b")),
                ArtifactLocation.builder()
                    .setRelativePath("java/com/test2.manifest")
                    .setIsSource(true)
                    .build())
            .build();
    Map<TargetKey, Map<ArtifactLocation, String>> manifestMap =
        readPackageManifestFiles(manifests, getDecoder("/root"));

    assertThat(manifestMap).hasSize(2);

    assertThat(manifestMap.get(TargetKey.forPlainTarget(new Label("//a:a"))))
        .containsEntry(
            ArtifactLocation.builder()
                .setRelativePath("java/com/google/Bla.java")
                .setIsSource(true)
                .build(),
            "com.google");
    assertThat(manifestMap.get(TargetKey.forPlainTarget(new Label("//a:a"))))
        .containsEntry(
            ArtifactLocation.builder()
                .setRelativePath("java/com/google/Foo.java")
                .setIsSource(true)
                .build(),
            "com.google.subpackage");
    assertThat(manifestMap.get(TargetKey.forPlainTarget(new Label("//b:b"))))
        .containsEntry(
            ArtifactLocation.builder()
                .setRelativePath("java/com/google/other/Temp.java")
                .setIsSource(true)
                .build(),
            "com.google.other");
  }

  @Test
  public void testManifestMissingSourcesFallback() throws Exception {
    setPackageManifest(
        "/root/java/com/test.manifest",
        ImmutableList.of("java/com/google/Bla.java", "java/com/google/Foo.java"),
        ImmutableList.of("com.google", "com.google"));

    mockInputStreamProvider.addFile(
        "/root/java/com/google/subpackage/Bla.java",
        "package com.google.different;\n public class Bla {}");

    ImmutableMap<TargetKey, ArtifactLocation> manifests =
        ImmutableMap.<TargetKey, ArtifactLocation>builder()
            .put(
                TargetKey.forPlainTarget(LABEL),
                ArtifactLocation.builder()
                    .setRelativePath("java/com/test.manifest")
                    .setIsSource(true)
                    .build())
            .build();

    List<SourceArtifact> sourceArtifacts =
        ImmutableList.of(
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Bla.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/Foo.java")
                        .setIsSource(true))
                .build(),
            SourceArtifact.builder(TargetKey.forPlainTarget(LABEL))
                .setArtifactLocation(
                    ArtifactLocation.builder()
                        .setRelativePath("java/com/google/subpackage/Bla.java")
                        .setIsSource(true))
                .build());

    ImmutableList<BlazeContentEntry> result =
        sourceDirectoryCalculator.calculateContentEntries(
            project,
            context,
            workspaceRoot,
            getDecoder("/root"),
            ImmutableList.of(new WorkspacePath("java/com/google")),
            sourceArtifacts,
            manifests);

    issues.assertNoIssues();
    assertThat(result)
        .containsExactly(
            BlazeContentEntry.builder("/root/java/com/google")
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google")
                        .setPackagePrefix("com.google")
                        .build())
                .addSource(
                    BlazeSourceDirectory.builder("/root/java/com/google/subpackage")
                        .setPackagePrefix("com.google.different")
                        .build())
                .build());
  }

  private void setPackageManifest(
      String manifestPath, List<String> sourceRelativePaths, List<String> packages) {
    PackageManifest.Builder manifest = PackageManifest.newBuilder();
    for (int i = 0; i < sourceRelativePaths.size(); i++) {
      String sourceRelativePath = sourceRelativePaths.get(i);
      PackageManifestOuterClass.ArtifactLocation source =
          PackageManifestOuterClass.ArtifactLocation.newBuilder()
              .setRelativePath(sourceRelativePath)
              .setIsSource(true)
              .build();
      manifest.addSources(
          JavaSourcePackage.newBuilder()
              .setArtifactLocation(source)
              .setPackageString(packages.get(i)));
    }
    mockInputStreamProvider.addFile(manifestPath, manifest.build().toByteArray());
  }

  private void setNewFormatPackageManifest(
      String manifestPath,
      List<PackageManifestOuterClass.ArtifactLocation> sources,
      List<String> packages) {
    PackageManifest.Builder manifest = PackageManifest.newBuilder();
    for (int i = 0; i < sources.size(); i++) {
      manifest.addSources(
          JavaSourcePackage.newBuilder()
              .setArtifactLocation(sources.get(i))
              .setPackageString(packages.get(i)));
    }
    mockInputStreamProvider.addFile(manifestPath, manifest.build().toByteArray());
  }

  private static ArtifactLocationDecoder getDecoder(String rootPath) {
    File root = new File(rootPath);
    WorkspaceRoot workspaceRoot = new WorkspaceRoot(root);
    BlazeRoots roots =
        new BlazeRoots(
            root,
            ImmutableList.of(root),
            new ExecutionRootPath("out/crosstool/bin"),
            new ExecutionRootPath("out/crosstool/gen"),
            null);
    return new ArtifactLocationDecoderImpl(
        roots, new WorkspacePathResolverImpl(workspaceRoot, roots));
  }

  private static class MockInputStreamProvider implements InputStreamProvider {

    private final Map<String, InputStream> javaFiles = new HashMap<String, InputStream>();

    public MockInputStreamProvider addFile(String filePath, String javaSrc) {
      try {
        addFile(filePath, javaSrc.getBytes("UTF-8"));
      } catch (UnsupportedEncodingException e) {
        fail(e.getMessage());
      }
      return this;
    }

    public MockInputStreamProvider addFile(String filePath, byte[] contents) {
      javaFiles.put(filePath, new ByteArrayInputStream(contents));
      return this;
    }

    @Override
    public InputStream getFile(@NotNull File path) throws FileNotFoundException {
      final InputStream inputStream = javaFiles.get(path.getPath());
      if (inputStream == null) {
        throw new FileNotFoundException(
            path + " has not been mapped into MockInputStreamProvider.");
      }
      return inputStream;
    }
  }

  private Map<TargetKey, Map<ArtifactLocation, String>> readPackageManifestFiles(
      Map<TargetKey, ArtifactLocation> manifests, ArtifactLocationDecoder decoder) {
    return PackageManifestReader.getInstance()
        .readPackageManifestFiles(
            project, context, decoder, manifests, MoreExecutors.sameThreadExecutor());
  }

  static class MockFileAttributeProvider extends FileAttributeProvider {
    @Override
    public long getFileModifiedTime(@NotNull File file) {
      return 1;
    }
  }
}
