// 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.runtime;

import com.google.common.collect.ConcurrentHashMultiset;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multiset;
import com.google.devtools.build.lib.actions.ActionResult;
import com.google.devtools.build.lib.actions.SpawnResult;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import javax.annotation.concurrent.ThreadSafe;

/** Collects results from SpawnResult. */
@ThreadSafe
public class SpawnStats {
  private static final ImmutableList<String> REPORT_FIRST =
      ImmutableList.of("disk cache hit", "remote cache hit");

  private final ConcurrentHashMultiset<String> runners = ConcurrentHashMultiset.create();
  private final AtomicLong totalWallTimeMillis = new AtomicLong();
  private final AtomicInteger totalNumberOfActions = new AtomicInteger();

  public void countActionResult(ActionResult actionResult) {
    for (SpawnResult r : actionResult.spawnResults()) {
      countRunnerName(r.getRunnerName());
      totalWallTimeMillis.addAndGet(r.getMetrics().executionWallTimeInMs());
    }
  }

  public void countRunnerName(String runner) {
    runners.add(runner);
  }

  public void incrementActionCount() {
    totalNumberOfActions.incrementAndGet();
  }

  public long getTotalWallTimeMillis() {
    return totalWallTimeMillis.get();
  }

  /*
   * Returns a human-readable summary of spawns counted.
   */
  public ImmutableMap<String, Integer> getSummary() {
    return getSummary(REPORT_FIRST);
  }

  /*
   * Returns a human-readable summary of spawns counted.
   */
  public ImmutableMap<String, Integer> getSummary(ImmutableList<String> reportFirst) {
    ImmutableMap.Builder<String, Integer> result = ImmutableMap.builder();
    int numActionsWithoutInternal = runners.size();
    int numActionsTotal = totalNumberOfActions.get();
    result.put("total", numActionsTotal);

    // First report cache results.
    for (String s : reportFirst) {
      int count = runners.setCount(s, 0);
      if (count > 0) {
        result.put(s, count);
      }
    }

    // Account for internal actions such as SymlinkTree.
    if (numActionsWithoutInternal < numActionsTotal) {
      result.put("internal", numActionsTotal - numActionsWithoutInternal);
    }

    // Sort the rest alphabetically
    ArrayList<Multiset.Entry<String>> list = new ArrayList<>(runners.entrySet());
    Collections.sort(list, Comparator.comparing(e -> e.getElement()));

    for (Multiset.Entry<String> e : list) {
      result.put(e.getElement(), e.getCount());
    }

    return result.buildOrThrow();
  }

  public static String convertSummaryToString(ImmutableMap<String, Integer> spawnSummary) {
    Integer total = spawnSummary.get("total");
    if (total == 0) {
      return "0 processes.";
    }

    StringBuilder stringSummary = new StringBuilder();
    stringSummary.append(total).append(" process");
    if (total > 1) {
      stringSummary.append("es");
    }
    String separator = ": ";

    for (Map.Entry<String, Integer> runnerStats : spawnSummary.entrySet()) {
      if ("total".equals(runnerStats.getKey())) {
        continue;
      }
      stringSummary.append(separator);
      separator = ", ";
      stringSummary.append(runnerStats.getValue()).append(' ').append(runnerStats.getKey());
    }
    stringSummary.append('.');
    return stringSummary.toString();
  }
}
