// Copyright 2022 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 static java.util.Map.entry;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;

/**
 * Used to inject a whole counter series (or even multiple) in one go in the JSON trace profile;
 * these could be used to represent CPU or memory usages over the course of an invocation (as
 * opposed to individual tasks such as executing an action).
 */
final class CounterSeriesTraceData implements TraceData {
  private final Map<ProfilerTask, double[]> counterSeriesMap;
  private final Duration profileStart;
  private final Duration bucketDuration;
  private final int len;
  private String displayName;
  @Nullable private String colorName;

  /**
   * If multiple series are passed: - they will be rendered as stacked chart; - we assume they all
   * have the same length; - display name and color are picked from the first profile task in the
   * map. However, colors the remaining series are picked arbitrarily by the Trace renderer.
   */
  CounterSeriesTraceData(
      Map<ProfilerTask, double[]> counterSeriesMap,
      Duration profileStart,
      Duration bucketDuration) {
    Integer len = null;
    for (ProfilerTask profilerTask : counterSeriesMap.keySet()) {
      Preconditions.checkState(COUNTER_TASK_TO_SERIES_NAME.containsKey(profilerTask));
      if (len == null) {
        len = counterSeriesMap.get(profilerTask).length;

        this.displayName = profilerTask.description;

        // Pick acceptable counter colors manually, unfortunately we have to pick from these
        // weird reserved names from
        // https://github.com/catapult-project/catapult/blob/master/tracing/tracing/base/color_scheme.html
        this.colorName = COUNTER_TASK_TO_COLOR.get(profilerTask);
      } else {
        Preconditions.checkState(len.equals(counterSeriesMap.get(profilerTask).length));
      }
    }
    this.len = len;
    this.counterSeriesMap = counterSeriesMap;
    this.profileStart = profileStart;
    this.bucketDuration = bucketDuration;

  }

  // Pick acceptable counter colors manually, unfortunately we have to pick from these
  // weird reserved names from
  // https://github.com/catapult-project/catapult/blob/master/tracing/tracing/base/color_scheme.html
  private static final ImmutableMap<ProfilerTask, String> COUNTER_TASK_TO_COLOR =
      ImmutableMap.ofEntries(
          entry(ProfilerTask.LOCAL_CPU_USAGE, "good"),
          entry(ProfilerTask.SYSTEM_CPU_USAGE, "rail_load"),
          entry(ProfilerTask.LOCAL_MEMORY_USAGE, "olive"),
          entry(ProfilerTask.SYSTEM_MEMORY_USAGE, "bad"),
          entry(ProfilerTask.SYSTEM_NETWORK_UP_USAGE, "rail_response"),
          entry(ProfilerTask.SYSTEM_NETWORK_DOWN_USAGE, "rail_response"),
          entry(ProfilerTask.WORKERS_MEMORY_USAGE, "rail_animation"),
          entry(ProfilerTask.SYSTEM_LOAD_AVERAGE, "generic_work"),
          entry(ProfilerTask.MEMORY_USAGE_ESTIMATION, "rail_idle"),
          entry(ProfilerTask.CPU_USAGE_ESTIMATION, "cq_build_attempt_passed"),
          entry(ProfilerTask.PRESSURE_STALL_IO, "rail_idle"),
          entry(ProfilerTask.PRESSURE_STALL_MEMORY, "rail_animation"));

  private static final ImmutableMap<ProfilerTask, String> COUNTER_TASK_TO_SERIES_NAME =
      ImmutableMap.ofEntries(
          entry(ProfilerTask.ACTION_COUNTS, "action"),
          entry(ProfilerTask.ACTION_CACHE_COUNTS, "local action cache"),
          entry(ProfilerTask.LOCAL_CPU_USAGE, "cpu"),
          entry(ProfilerTask.SYSTEM_CPU_USAGE, "system cpu"),
          entry(ProfilerTask.LOCAL_MEMORY_USAGE, "memory"),
          entry(ProfilerTask.SYSTEM_MEMORY_USAGE, "system memory"),
          entry(ProfilerTask.SYSTEM_NETWORK_UP_USAGE, "system network up (Mbps)"),
          entry(ProfilerTask.SYSTEM_NETWORK_DOWN_USAGE, "system network down (Mbps)"),
          entry(ProfilerTask.WORKERS_MEMORY_USAGE, "workers memory"),
          entry(ProfilerTask.SYSTEM_LOAD_AVERAGE, "load"),
          entry(ProfilerTask.MEMORY_USAGE_ESTIMATION, "estimated memory"),
          entry(ProfilerTask.CPU_USAGE_ESTIMATION, "estimated cpu"),
          entry(ProfilerTask.PRESSURE_STALL_IO, "i/o pressure"),
          entry(ProfilerTask.PRESSURE_STALL_MEMORY, "memory pressure"));

  @Override
  public void writeTraceData(JsonWriter jsonWriter, long profileStartTimeNanos) throws IOException {
    // See
    // https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU/preview#heading=h.msg3086636uq
    // for how counter series are represented in the Chrome Trace Event format.
    for (int i = 0; i < len; i++) {
      long timeNanos = profileStart.plus(bucketDuration.multipliedBy(i)).toNanos();
      jsonWriter.setIndent("  ");
      jsonWriter.beginObject();
      jsonWriter.setIndent("");
      jsonWriter.name("name").value(displayName);
      jsonWriter.name("pid").value(1);
      if (colorName != null) {
        jsonWriter.name("cname").value(colorName);
      }
      jsonWriter.name("ph").value("C");
      jsonWriter.name("ts").value(TimeUnit.NANOSECONDS.toMicros(timeNanos - profileStartTimeNanos));
      jsonWriter.name("args");

      jsonWriter.beginObject();
      for (ProfilerTask profilerTask : counterSeriesMap.keySet()) {
        double value = counterSeriesMap.get(profilerTask)[i];
        // Skip counts equal to zero. They will show up as a thin line in the profile.
        if (Math.abs(value) > 0.00001) {
          jsonWriter.name(COUNTER_TASK_TO_SERIES_NAME.get(profilerTask)).value(value);
        }
      }
      jsonWriter.endObject();

      jsonWriter.endObject();
    }
  }
}
