// Copyright 2020 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.devtools.build.lib.packages.metrics;

import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.cmdline.Label;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.collect.ImmutableSortedKeyMap;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.Target;
import com.google.devtools.build.lib.packages.metrics.ExtremaPackageLoadingListener.PackageIdentifierAndLong;
import com.google.devtools.build.lib.packages.metrics.ExtremaPackageLoadingListener.TopPackages;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import java.util.List;
import java.util.Map;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link ExtremaPackageLoadingListener}. */
@RunWith(JUnit4.class)
public class ExtremaPackageLoadingListenerTest {

  private final ExtremaPackageLoadingListener underTest = new ExtremaPackageLoadingListener();

  @Test
  public void testRecordsTopSlowestPackagesPerBuild() {
    underTest.setNumPackagesToTrack(2);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg1",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 42_000_000);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg2",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 43_000_000);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg3",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 44_000_000);

    assertThat(toStrings(underTest.getAndResetTopPackages().getSlowestPackages()))
        .containsExactly("my/pkg3 (44)", "my/pkg2 (43)")
        .inOrder();

    assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
  }

  @Test
  public void testRecordsTopLargestPackagesPerBuild() {
    underTest.setNumPackagesToTrack(2);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg1",
            ImmutableMap.of("target1", mock(Target.class)),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg2",
            ImmutableMap.of("target1", mock(Target.class), "target2", mock(Target.class)),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg3",
            ImmutableMap.of(
                "target1",
                mock(Target.class),
                "target2",
                mock(Target.class),
                "target3",
                mock(Target.class)),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    assertThat(toStrings(underTest.getAndResetTopPackages().getLargestPackages()))
        .containsExactly("my/pkg3 (3)", "my/pkg2 (2)")
        .inOrder();

    assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
  }

  @Test
  public void testRecordsTransitiveLoadsPerBuild() {
    underTest.setNumPackagesToTrack(2);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg1",
            /*targets=*/ ImmutableMap.of(),
            ImmutableList.of(Label.parseAbsoluteUnchecked("//load:1.bzl"))),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg2",
            /*targets=*/ ImmutableMap.of(),
            ImmutableList.of(
                Label.parseAbsoluteUnchecked("//load:1.bzl"),
                Label.parseAbsoluteUnchecked("//load:2.bzl"))),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg3",
            /*targets=*/ ImmutableMap.of(),
            ImmutableList.of(
                Label.parseAbsoluteUnchecked("//load:1.bzl"),
                Label.parseAbsoluteUnchecked("//load:2.bzl"),
                Label.parseAbsoluteUnchecked("//load:3.bzl"))),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 100);

    assertThat(toStrings(underTest.getAndResetTopPackages().getPackagesWithMostTransitiveLoads()))
        .containsExactly("my/pkg3 (3)", "my/pkg2 (2)")
        .inOrder();

    assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
  }

  @Test
  public void testRecordsMostComputationStepsPerBuild() {
    underTest.setNumPackagesToTrack(2);

    Package mockPackage1 =
        mockPackage(
            "my/pkg1",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of());
    when(mockPackage1.getComputationSteps()).thenReturn(1000L);
    underTest.onLoadingCompleteAndSuccessful(
        mockPackage1, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);

    Package mockPackage2 =
        mockPackage(
            "my/pkg2",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of());
    when(mockPackage2.getComputationSteps()).thenReturn(100L);
    underTest.onLoadingCompleteAndSuccessful(
        mockPackage2, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);

    Package mockPackage3 =
        mockPackage(
            "my/pkg3",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of());
    when(mockPackage3.getComputationSteps()).thenReturn(10L);
    underTest.onLoadingCompleteAndSuccessful(
        mockPackage3, StarlarkSemantics.DEFAULT, /*loadTimeNanos=*/ 100);

    assertThat(toStrings(underTest.getAndResetTopPackages().getPackagesWithMostComputationSteps()))
        .containsExactly("my/pkg1 (1000)", "my/pkg2 (100)")
        .inOrder();

    assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
  }

  @Test
  public void testDoesntRecordAnythingWhenNumPackagesToTrackIsZero() {
    underTest.setNumPackagesToTrack(0);

    underTest.onLoadingCompleteAndSuccessful(
        mockPackage(
            "my/pkg1",
            /*targets=*/ ImmutableMap.of(),
            /*starlarkDependencies=*/ ImmutableList.of()),
        StarlarkSemantics.DEFAULT,
        /*loadTimeNanos=*/ 42_000_000);

    assertAllTopPackagesEmpty(underTest.getAndResetTopPackages());
  }

  private static void assertAllTopPackagesEmpty(TopPackages topPackages) {
    assertThat(topPackages.getSlowestPackages()).isEmpty();
    assertThat(topPackages.getLargestPackages()).isEmpty();
    assertThat(topPackages.getPackagesWithMostTransitiveLoads()).isEmpty();
    assertThat(topPackages.getPackagesWithMostComputationSteps()).isEmpty();
  }

  private static Package mockPackage(
      String pkgIdString, Map<String, Target> targets, List<Label> starlarkDependencies) {
    Package mockPackage = mock(Package.class);
    when(mockPackage.getPackageIdentifier())
        .thenReturn(PackageIdentifier.createInMainRepo(pkgIdString));
    when(mockPackage.getTargets()).thenReturn(ImmutableSortedKeyMap.copyOf(targets));
    when(mockPackage.getStarlarkFileDependencies())
        .thenReturn(ImmutableList.copyOf(starlarkDependencies));
    return mockPackage;
  }

  private static ImmutableList<String> toStrings(List<PackageIdentifierAndLong> from) {
    return from.stream().map(v -> v.toString()).collect(ImmutableList.toImmutableList());
  }
}
