// 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 com.google.common.base.Preconditions;
import com.google.devtools.build.lib.cmdline.PackageIdentifier;
import com.google.devtools.build.lib.collect.Extrema;
import com.google.devtools.build.lib.packages.Package;
import com.google.devtools.build.lib.packages.PackageLoadingListener;
import com.google.devtools.build.lib.syntax.StarlarkSemantics;
import java.util.List;
import java.util.concurrent.TimeUnit;
import javax.annotation.concurrent.GuardedBy;

/** Tracks per-invocation extreme package loading events. */
class ExtremaPackageLoadingListener implements PackageLoadingListener {
  @GuardedBy("this")
  private int currentNumPackagesToTrack;

  @GuardedBy("this")
  private Extrema<PackageIdentifierAndLong> slowestPackagesToLoad;

  @GuardedBy("this")
  private Extrema<PackageIdentifierAndLong> largestPackages;

  @GuardedBy("this")
  private Extrema<PackageIdentifierAndLong> packagesWithMostTransitiveLoads;

  @GuardedBy("this")
  private Extrema<PackageIdentifierAndLong> packagesWithMostComputationSteps;

  ExtremaPackageLoadingListener() {
    this.currentNumPackagesToTrack = 0;
    this.slowestPackagesToLoad = Extrema.max(0);
    this.largestPackages = Extrema.max(0);
    this.packagesWithMostTransitiveLoads = Extrema.max(0);
    this.packagesWithMostComputationSteps = Extrema.max(0);
  }

  synchronized void setNumPackagesToTrack(int numPackagesToTrack) {
    Preconditions.checkArgument(numPackagesToTrack >= 0, "num packages must be >= 0");
    if (numPackagesToTrack == currentNumPackagesToTrack) {
      // Micro-optimization to avoid turning over collections.
      clear();
      return;
    }

    currentNumPackagesToTrack = numPackagesToTrack;
    this.slowestPackagesToLoad = Extrema.max(currentNumPackagesToTrack);
    this.largestPackages = Extrema.max(currentNumPackagesToTrack);
    this.packagesWithMostTransitiveLoads = Extrema.max(currentNumPackagesToTrack);
    this.packagesWithMostComputationSteps = Extrema.max(currentNumPackagesToTrack);
  }

  @Override
  public synchronized void onLoadingCompleteAndSuccessful(
      Package pkg, StarlarkSemantics starlarkSemantics, long loadTimeNanos) {
    if (currentNumPackagesToTrack == 0) {
      // Micro-optimization - no need to track.
      return;
    }

    long loadTimeMillis = TimeUnit.MILLISECONDS.convert(loadTimeNanos, TimeUnit.NANOSECONDS);
    slowestPackagesToLoad.aggregate(
        new PackageIdentifierAndLong(pkg.getPackageIdentifier(), loadTimeMillis));

    packagesWithMostComputationSteps.aggregate(
        new PackageIdentifierAndLong(pkg.getPackageIdentifier(), pkg.getComputationSteps()));

    largestPackages.aggregate(
        new PackageIdentifierAndLong(pkg.getPackageIdentifier(), pkg.getTargets().size()));

    packagesWithMostTransitiveLoads.aggregate(
        new PackageIdentifierAndLong(
            pkg.getPackageIdentifier(), pkg.getStarlarkFileDependencies().size()));
  }

  synchronized TopPackages getAndResetTopPackages() {
    TopPackages result =
        new TopPackages(
            slowestPackagesToLoad.getExtremeElements(),
            packagesWithMostComputationSteps.getExtremeElements(),
            largestPackages.getExtremeElements(),
            packagesWithMostTransitiveLoads.getExtremeElements());
    clear();
    return result;
  }

  private synchronized void clear() {
    slowestPackagesToLoad.clear();
    packagesWithMostComputationSteps.clear();
    largestPackages.clear();
    packagesWithMostTransitiveLoads.clear();
  }

  static class TopPackages {
    private final List<PackageIdentifierAndLong> slowestPackages;
    private final List<PackageIdentifierAndLong> packagesWithMostComputationSteps;
    private final List<PackageIdentifierAndLong> largestPackages;
    private final List<PackageIdentifierAndLong> packagesWithMostTransitiveLoads;

    private TopPackages(
        List<PackageIdentifierAndLong> slowestPackages,
        List<PackageIdentifierAndLong> packagesWithMostComputationSteps,
        List<PackageIdentifierAndLong> largestPackages,
        List<PackageIdentifierAndLong> packagesWithMostTransitiveLoads) {
      this.slowestPackages = slowestPackages;
      this.packagesWithMostComputationSteps = packagesWithMostComputationSteps;
      this.largestPackages = largestPackages;
      this.packagesWithMostTransitiveLoads = packagesWithMostTransitiveLoads;
    }

    List<PackageIdentifierAndLong> getSlowestPackages() {
      return slowestPackages;
    }

    List<PackageIdentifierAndLong> getPackagesWithMostComputationSteps() {
      return packagesWithMostComputationSteps;
    }

    List<PackageIdentifierAndLong> getLargestPackages() {
      return largestPackages;
    }

    List<PackageIdentifierAndLong> getPackagesWithMostTransitiveLoads() {
      return packagesWithMostTransitiveLoads;
    }
  }

  static class PackageIdentifierAndLong implements Comparable<PackageIdentifierAndLong> {
    private final PackageIdentifier pkgId;
    private final long val;

    private PackageIdentifierAndLong(PackageIdentifier pkgId, long val) {
      this.pkgId = pkgId;
      this.val = val;
    }

    @Override
    public int compareTo(PackageIdentifierAndLong other) {
      return Long.compare(val, other.val);
    }

    @Override
    public String toString() {
      return String.format("%s (%d)", pkgId, val);
    }
  }
}
