// Copyright 2014 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.Predicate;
import java.util.EnumSet;

/**
 * All possible types of profiler tasks. Each type also defines description and
 * minimum duration in nanoseconds for it to be recorded as separate event and
 * not just be aggregated into the parent event.
 */
public enum ProfilerTask {
  /* WARNING:
   * Add new Tasks at the end (before Unknown) to not break the profiles that people have created!
   * The profile file format uses the ordinal() of this enumeration to identify the task.
   */
  PHASE("build phase marker", 0x336699),
  ACTION("action processing", 0x666699),
  __ACTION_BUILDER("parallel builder completion queue", 0xCC3399), // unused
  __ACTION_SUBMIT("execution queue submission", 0xCC3399), // unused
  ACTION_CHECK("action dependency checking", 10000000, 0x999933, 0, false),
  ACTION_EXECUTE("action execution", 0x99CCFF),
  ACTION_LOCK("action resource lock", 10000000, 0xCC9933, 0, false),
  ACTION_RELEASE("action resource release", 10000000, 0x006666, 0, false),
  __ACTION_GRAPH("action graph dependency", 0x3399FF), // unused
  ACTION_UPDATE("update action information", 10000000, 0x993300, 0, false),
  ACTION_COMPLETE("complete action execution", 0xCCCC99),
  INFO("general information", 0x000066),
  __EXCEPTION("exception", 0xFFCC66), // unused
  CREATE_PACKAGE("package creation", 0x6699CC),
  __PACKAGE_VALIDITY_CHECK("package validity check", 0x336699), // unused
  __SPAWN("local process spawn", 0x663366), // unused
  REMOTE_EXECUTION("remote action execution", 0x9999CC),
  LOCAL_EXECUTION("local action execution", 0xCCCCCC),
  SCANNER("include scanner", 0x669999),
  // 30 is a good number because the slowest items are stored in a heap, with temporarily
  // one more element, and with 31 items, a heap becomes a complete binary tree
  LOCAL_PARSE("Local parse to prepare for remote execution", 50000000, 0x6699CC, 30, false),
  UPLOAD_TIME("Remote execution upload time", 50000000, 0x6699CC, 0, false),
  PROCESS_TIME("Remote execution process wall time", 50000000, 0xF999CC, 0, false),
  REMOTE_QUEUE("Remote execution queuing time", 50000000, 0xCC6600, 0, false),
  REMOTE_SETUP("Remote execution setup", 50000000, 0xA999CC, 0, false),
  FETCH("Remote execution file fetching", 50000000, 0xBB99CC, 0, false),
  VFS_STAT("VFS stat", 10000000, 0x9999FF, 30, true),
  VFS_DIR("VFS readdir", 10000000, 0x0066CC, 30, true),
  VFS_READLINK("VFS readlink", 10000000, 0x99CCCC, 30, true),
  // TODO(olaola): rename to VFS_DIGEST. This refers to all digest function computations.
  VFS_MD5("VFS md5", 10000000, 0x999999, 30, true),
  VFS_XATTR("VFS xattr", 10000000, 0x9999DD, 30, true),
  VFS_DELETE("VFS delete", 10000000, 0xFFCC00, 0, true),
  VFS_OPEN("VFS open", 10000000, 0x009999, 30, true),
  VFS_READ("VFS read", 10000000, 0x99CC33, 30, true),
  VFS_WRITE("VFS write", 10000000, 0xFF9900, 30, true),
  VFS_GLOB("globbing", -1, 0x999966, 30, true),
  VFS_VMFS_STAT("VMFS stat", 10000000, 0x9999FF, 0, true),
  VFS_VMFS_DIR("VMFS readdir", 10000000, 0x0066CC, 0, true),
  VFS_VMFS_READ("VMFS read", 10000000, 0x99CC33, 0, true),
  WAIT("thread wait", 5000000, 0x66CCCC, 0, false),
  __CONFIGURED_TARGET("configured target creation", 0x663300), // unused
  THREAD_NAME("thread name", 0x996600), // Do not use directly!
  __TEST("for testing only", 0x000000), // unused
  SKYFRAME_EVAL("skyframe evaluator", 0xCC9900),
  SKYFUNCTION("skyfunction", 0xCC6600),
  CRITICAL_PATH("critical path", 0x666699),
  CRITICAL_PATH_COMPONENT("critical path component", 0x666699),
  HANDLE_GC_NOTIFICATION("gc notification", 0x996633),
  LOCAL_CPU_USAGE("cpu counters", 0x000000),
  __INCLUSION_PARSE("inclusion parse", 0x000000), // unused
  __PROCESS_SCAN("process scan", 0x000000), // unused
  __LOOP_OUTPUT_ARTIFACTS("loop output artifacts"), // unused
  __LOCATE_RELATIVE("locate relative"), // unused
  __CONSTRUCT_INCLUDE_PATHS("construct include paths"), // unused
  __PARSE_AND_HINTS_RESULTS("parse and hints results"), // unused
  __PROCESS_RESULTS_AND_ENQUEUE("process results and enqueue"), // unused
  STARLARK_PARSER("Starlark Parser"),
  STARLARK_USER_FN("Starlark user function call", -0xCC0033),
  STARLARK_BUILTIN_FN("Starlark builtin function call", 0x990033),
  STARLARK_USER_COMPILED_FN("Starlark compiled user function call", 0xCC0033),
  ACTION_FS_STAGING("Staging per-action file system", 0x000000),
  UNKNOWN("Unknown event",  0x339966);

  // Size of the ProfilerTask value space.
  public static final int TASK_COUNT = ProfilerTask.values().length;

  /** Human readable description for the task. */
  public final String description;
  /**
   * Threshold for skipping tasks in the profile in nanoseconds, unless --record_full_profiler_data
   * is used.
   */
  public final long minDuration;
  /** Default color of the task, when rendered in a chart. */
  public final int color;
  /** How many of the slowest instances to keep. If 0, no slowest instance calculation is done. */
  public final int slowestInstancesCount;
  /** True if the metric records VFS operations */
  private final boolean vfs;

  private ProfilerTask(
      String description, long minDuration, int color, int slowestInstanceCount, boolean vfs) {
    this.description = description;
    this.minDuration = minDuration;
    this.color = color;
    this.slowestInstancesCount = slowestInstanceCount;
    this.vfs = vfs;
  }

  private ProfilerTask(String description, int color) {
    this(
        description,
        /* minDuration= */ -1,
        color,
        /* slowestInstanceCount= */ 0,
        /* vfs= */ false);
  }

  private ProfilerTask(String description) {
    this(description, -1, 0x000000, 0, /* vfs= */ false);
  }

  /** Whether the Profiler collects the slowest instances of this task. */
  public boolean collectsSlowestInstances() {
    return slowestInstancesCount > 0;
  }

  /**
   * Build a set containing all ProfilerTasks for which the given predicate is true.
   */
  public static EnumSet<ProfilerTask> allSatisfying(Predicate<ProfilerTask> predicate) {
    EnumSet<ProfilerTask> set = EnumSet.noneOf(ProfilerTask.class);
    for (ProfilerTask taskType : values()) {
      if (predicate.apply(taskType)) {
        set.add(taskType);
      }
    }
    return set;
  }

  public boolean isVfs() {
    return vfs;
  }

  public boolean isStarlark() {
    return description.startsWith("Starlark ");
  }
}
