// Copyright 2018 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.profiler;

import com.google.common.base.Ascii;
import com.google.common.flogger.GoogleLogger;
import com.google.common.flogger.LogSites;
import com.google.devtools.build.lib.profiler.AutoProfiler.ElapsedTimeReceiver;
import java.time.Duration;
import java.util.concurrent.TimeUnit;

/** Utility for creating {@link AutoProfiler} instances from {@link GoogleLogger} instances. */
public class GoogleAutoProfilerUtils {
  private static final GoogleLogger selfLogger = GoogleLogger.forEnclosingClass();
  private static final String LOGGING_MESSAGE_TEMPLATE =
      "Spent %d " + Ascii.toLowerCase(TimeUnit.MILLISECONDS.toString()) + " doing %s";

  private GoogleAutoProfilerUtils() {}

  /**
   * Use {@link #logged(String, Duration)} instead. This should only be called when caller has a
   * specially configured {@code logger} and cannot use this class's one.
   */
  public static AutoProfiler logged(
      String description, GoogleLogger logger, Duration minTimeForLogging) {
    return AutoProfiler.create(makeReceiver(description, logger, minTimeForLogging));
  }

  public static AutoProfiler logged(String description, Duration minTimeForLogging) {
    return logged(description, selfLogger, minTimeForLogging);
  }

  public static AutoProfiler logged(String description) {
    return AutoProfiler.create(createSimpleLogger(description));
  }

  private static ElapsedTimeReceiver createSimpleLogger(String description) {
    return elapsedTimeNanos -> log(selfLogger, elapsedTimeNanos, description);
  }

  /**
   * Returns an {@link AutoProfiler} that, when closed, records the elapsed time using {@link
   * Profiler} and also logs it (in milliseconds) to the default logger.
   *
   * <p>The returned {@link AutoProfiler} is thread-safe.
   */
  public static AutoProfiler profiledAndLogged(
      String taskDescription, ProfilerTask profilerTaskType) {
    ElapsedTimeReceiver profilingReceiver =
        new AutoProfiler.ProfilingElapsedTimeReceiver(taskDescription, profilerTaskType);
    return AutoProfiler.create(
        new SequencedElapsedTimeReceiver(profilingReceiver, createSimpleLogger(taskDescription)));
  }

  /**
   * Returns an {@link AutoProfiler} that, when closed, will log if the operation exceeds provided
   * threshold and call the custom {@link ElapsedTimeReceiver} for any duration.
   */
  public static AutoProfiler loggedAndCustomReceiver(
      String taskDescription, Duration minTimeForLogging, ElapsedTimeReceiver customReceiver) {
    return AutoProfiler.create(
        new SequencedElapsedTimeReceiver(
            makeReceiver(taskDescription, selfLogger, minTimeForLogging), customReceiver));
  }

  private static ElapsedTimeReceiver makeReceiver(
      String description, GoogleLogger logger, Duration minTimeForLogging) {
    return new FloggerElapsedTimeReceiver(description, logger, minTimeForLogging);
  }

  /** {@link ElapsedTimeReceiver} that will not log a message if the time elapsed is too small. */
  private static class FloggerElapsedTimeReceiver implements ElapsedTimeReceiver {
    // Some classes in Google-internal Blaze use a specially configured logger. When those classes
    // record elapsed time using this library, they pass their logger in here, which we use instead
    // of this library's default selfLogger.
    private final GoogleLogger logger;
    private final String taskDescription;
    private final Duration minTimeForLogging;

    FloggerElapsedTimeReceiver(
        String taskDescription, GoogleLogger logger, Duration minTimeForLogging) {
      this.taskDescription = taskDescription;
      this.minTimeForLogging = minTimeForLogging;
      this.logger = logger;
    }

    @Override
    public final void accept(long elapsedTimeNanos) {
      // We avoid eagerly converting elapsedTimeNanos to a Duration to minimize garbage creation.
      if (elapsedTimeNanos < minTimeForLogging.toNanos()) {
        return;
      }
      log(logger, elapsedTimeNanos, taskDescription);
    }
  }

  private static void log(GoogleLogger logger, long elapsedTimeNanos, String taskDescription) {
    logger
        .atInfo()
        .withInjectedLogSite(LogSites.callerOf(AutoProfiler.class))
        .log(
            LOGGING_MESSAGE_TEMPLATE,
            // TODO(janakr): confirm that this doesn't show up as a source of garbage. Since it only
            //  happens when we're actually logging, it shouldn't.
            Duration.ofNanos(elapsedTimeNanos).toMillis(),
            taskDescription);
  }

  private static class SequencedElapsedTimeReceiver implements ElapsedTimeReceiver {
    private final ElapsedTimeReceiver firstReceiver;
    private final ElapsedTimeReceiver secondReceiver;

    private SequencedElapsedTimeReceiver(
        ElapsedTimeReceiver firstReceiver, ElapsedTimeReceiver secondReceiver) {
      this.firstReceiver = firstReceiver;
      this.secondReceiver = secondReceiver;
    }

    @Override
    public void accept(long elapsedTimeNanos) {
      firstReceiver.accept(elapsedTimeNanos);
      secondReceiver.accept(elapsedTimeNanos);
    }
  }
}
