// 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 com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** This class is used to insert metadata about threads into the JSON trace profile. */
class ThreadMetadata implements TraceData {
  private final String readableName;
  private final long threadId;
  private final long sortIndex;

  public ThreadMetadata(String readableName, long threadId) {
    this.readableName = readableName;
    this.threadId = threadId;
    this.sortIndex = getSortIndex(readableName);
  }

  public ThreadMetadata(String readableName, long threadId, long sortIndex) {
    this.readableName = readableName;
    this.threadId = threadId;
    this.sortIndex = sortIndex;
  }

  public ThreadMetadata() {
    this.readableName = getReadableName(Thread.currentThread().getName());
    this.threadId = Thread.currentThread().getId();
    this.sortIndex = getSortIndex(Thread.currentThread().getName());
  }

  // The JVM never returns 0 as thread ID, so we use that as fake thread ID for the critical path.
  static final long CRITICAL_PATH_THREAD_ID = 0;

  // In order to display the actions on the critical path in a nice way, we fake a thread for them.
  public static ThreadMetadata createFakeThreadMetadataForCriticalPath() {
    return new ThreadMetadata("Critical Path", CRITICAL_PATH_THREAD_ID, CRITICAL_PATH_SORT_INDEX);
  }

  private static boolean isMainThread(String threadName) {
    return threadName.startsWith("grpc-command");
  }

  private static boolean isGCThread(String threadName) {
    return threadName.equals("Notification Thread");
  }

  private static String getReadableName(String threadName) {
    if (isMainThread(threadName)) {
      return "Main Thread";
    }

    if (isGCThread(threadName)) {
      return "Garbage Collector";
    }

    return threadName;
  }

  /**
   * These constants describe ranges of threads. We suppose that there are no more than 10_000
   * threads of each kind, otherwise the profile becomes unreadable anyway. So the sort index of
   * skyframe threads is in range [10_000..20_000) for example.
   */
  private static final long SKYFRAME_EVALUATOR_SHIFT = 10_000;

  private static final long SKYFRAME_EVALUATOR_CPU_HEAVY_SHIFT = 20_000;
  private static final long SKYFRAME_EVALUATOR_EXECUTION_SHIFT = 30_000;
  private static final long SKYFRAME_EVALUATOR_MEMOIZING_SHIFT = 40_000;

  private static final long DYNAMIC_EXECUTION_SHIFT = 100_000;
  private static final long INCLUDE_SCANNER_SHIFT = 200_000;

  private static final long CRITICAL_PATH_SORT_INDEX = 0;
  private static final long MAIN_THREAD_SORT_INDEX = 1;
  private static final long GC_THREAD_SORT_INDEX = 2;
  private static final long MAX_SORT_INDEX = 1_000_000;

  private static final Pattern NUMBER_PATTERN = Pattern.compile("\\d+");

  private static long getSortIndex(String threadName) {
    if (isMainThread(threadName)) {
      return MAIN_THREAD_SORT_INDEX;
    }

    if (isGCThread(threadName)) {
      return GC_THREAD_SORT_INDEX;
    }

    Matcher numberMatcher = NUMBER_PATTERN.matcher(threadName);
    if (!numberMatcher.find()) {
      return MAX_SORT_INDEX;
    }

    long extractedNumber;
    try {
      extractedNumber = Long.parseLong(numberMatcher.group());
    } catch (NumberFormatException e) {
      // If the number cannot be parsed, e.g. is larger than a long, the actual position is not
      // really relevant.
      return MAX_SORT_INDEX;
    }

    if (threadName.startsWith("skyframe-evaluator")) {
      if (threadName.startsWith("skyframe-evaluator-cpu-heavy")) {
        return SKYFRAME_EVALUATOR_CPU_HEAVY_SHIFT + extractedNumber;
      }
      if (threadName.startsWith("skyframe-evaluator-execution")) {
        return SKYFRAME_EVALUATOR_EXECUTION_SHIFT + extractedNumber;
      }
      if (threadName.startsWith("skyframe-evaluator-memoizing")) {
        return SKYFRAME_EVALUATOR_MEMOIZING_SHIFT + extractedNumber;
      }
      return SKYFRAME_EVALUATOR_SHIFT + extractedNumber;
    }

    if (threadName.startsWith("dynamic-execution")) {
      return DYNAMIC_EXECUTION_SHIFT + extractedNumber;
    }

    if (threadName.startsWith("Include scanner")) {
      return INCLUDE_SCANNER_SHIFT + extractedNumber;
    }

    return MAX_SORT_INDEX;
  }

  @Override
  public void writeTraceData(JsonWriter jsonWriter, long profileStartTimeNanos) throws IOException {
    jsonWriter.setIndent("  ");
    jsonWriter.beginObject();
    jsonWriter.setIndent("");
    jsonWriter.name("name").value("thread_name");
    jsonWriter.name("ph").value("M");
    jsonWriter.name("pid").value(1);
    jsonWriter.name("tid").value(threadId);
    jsonWriter.name("args");

    jsonWriter.beginObject();
    jsonWriter.name("name").value(readableName);
    jsonWriter.endObject();

    jsonWriter.endObject();

    jsonWriter.setIndent("  ");
    jsonWriter.beginObject();
    jsonWriter.setIndent("");
    jsonWriter.name("name").value("thread_sort_index");
    jsonWriter.name("ph").value("M");
    jsonWriter.name("pid").value(1);
    jsonWriter.name("tid").value(threadId);
    jsonWriter.name("args");

    jsonWriter.beginObject();
    jsonWriter.name("sort_index").value(sortIndex);
    jsonWriter.endObject();

    jsonWriter.endObject();
  }
}
