// Copyright 2015 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.statistics;

import com.google.common.collect.Maps;
import com.google.common.collect.Maps.EntryTransformer;
import com.google.common.collect.Multimap;
import com.google.devtools.build.lib.profiler.ProfileInfo;
import com.google.devtools.build.lib.profiler.ProfileInfo.Task;
import com.google.devtools.build.lib.util.LongArrayList;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

/**
 * Extracts the execution times of user-defined and built-in Skylark functions and computes
 * statistics.
 *
 * <p>The statistics are separated for the total duration taken for a function call and the
 * "self duration" taken only within the function itself, but not within any subtask of the
 * corresponding {@link Task}.
 */
public final class SkylarkStatistics {

  private final Map<String, LongArrayList> userFunctionDurations;
  private final Map<String, LongArrayList> userCompiledDurations;
  private final Map<String, LongArrayList> builtinFunctionDurations;

  /**
   * Self duration is the time taken just within a function itself, but not other subtasks of it.
   */
  private final Map<String, LongArrayList> userFunctionSelfDurations;
  private final Map<String, LongArrayList> userCompiledSelfDurations;
  private final Map<String, LongArrayList> builtinFunctionSelfDurations;
  private long userTotalNanos;
  private long userCompiledTotalNanos;
  private long builtinTotalNanos;

  public SkylarkStatistics() {
    userFunctionDurations = new HashMap<>();
    userCompiledDurations = new HashMap<>();
    builtinFunctionDurations = new HashMap<>();
    userFunctionSelfDurations = new HashMap<>();
    userCompiledSelfDurations = new HashMap<>();
    builtinFunctionSelfDurations = new HashMap<>();
  }

  public SkylarkStatistics(ProfileInfo info) {
    this();
    addProfileInfo(info);
  }

  /**
   * Adds Skylark function task durations from a {@link ProfileInfo} file.
   */
  public void addProfileInfo(ProfileInfo info) {
    computeStatistics(
        info.getSkylarkUserFunctionTasks(),
        info.getCompiledSkylarkUserFunctionTasks(),
        info.getSkylarkBuiltinFunctionTasks());
  }

  /**
   * @return the total time taken by all calls to built-in Skylark functions
   */
  public long getBuiltinTotalNanos() {
    return builtinTotalNanos;
  }

  /**
   * @return the total time taken by all calls to user-defined Skylark functions
   */
  public long getCompiledUserTotalNanos() {
    return userCompiledTotalNanos;
  }

  /**
   * @return the total time taken by all calls to user-defined Skylark functions
   */
  public long getUserTotalNanos() {
    return userTotalNanos;
  }

  /**
   * @return The execution durations of all calls to built-in Skylark functions.
   */
  public Map<String, LongArrayList> getBuiltinFunctionDurations() {
    return builtinFunctionDurations;
  }

  /**
   * return The execution durations of all calls to built-in functions excluding the durations of
   * all subtasks.
   */
  public Map<String, LongArrayList> getBuiltinFunctionSelfDurations() {
    return builtinFunctionSelfDurations;
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the durations of each built-in function.
   * The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getBuiltinFunctionStatistics() {
    return buildTasksStatistics(builtinFunctionDurations);
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the self-times of each built-in function.
   * The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getBuiltinFunctionSelfStatistics() {
    return buildTasksStatistics(builtinFunctionSelfDurations);
  }

  /**
   * @return The execution durations of all calls to user-defined Skylark functions.
   */
  public Map<String, LongArrayList> getCompiledUserFunctionDurations() {
    return userCompiledDurations;
  }

  /**
   * return The execution durations of all calls to user-defined functions excluding the durations
   * of all subtasks.
   */
  public Map<String, LongArrayList> getCompiledUserFunctionSelfDurations() {
    return userCompiledSelfDurations;
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the durations of each user-defined
   * function. The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getCompiledUserFunctionStatistics() {
    return buildTasksStatistics(userCompiledDurations);
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the self-times of each user-defined
   * function. The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getCompiledUserFunctionSelfStatistics() {
    return buildTasksStatistics(userCompiledSelfDurations);
  }

  /**
   * @return The execution durations of all calls to user-defined Skylark functions.
   */
  public Map<String, LongArrayList> getUserFunctionDurations() {
    return userFunctionDurations;
  }

  /**
   * return The execution durations of all calls to user-defined functions excluding the durations
   * of all subtasks.
   */
  public Map<String, LongArrayList> getUserFunctionSelfDurations() {
    return userFunctionSelfDurations;
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the durations of each user-defined
   * function. The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getUserFunctionStatistics() {
    return buildTasksStatistics(userFunctionDurations);
  }

  /**
   * Builds and returns the {@link TasksStatistics} for the self-times of each user-defined
   * function. The return value is not cached and will be recomputed on another call.
   */
  public Map<String, TasksStatistics> getUserFunctionSelfStatistics() {
    return buildTasksStatistics(userFunctionSelfDurations);
  }

  /**
   * For each Skylark function get the list of durations and self durations from the task maps.
   */
  private void computeStatistics(
      Multimap<String, Task> userTasks,
      Multimap<String, Task> userCompiledTasks,
      Multimap<String, Task> builtinTasks) {
    userTotalNanos += addDurations(userTasks, userFunctionDurations, userFunctionSelfDurations);
    userCompiledTotalNanos +=
        addDurations(userCompiledTasks, userCompiledDurations, userCompiledSelfDurations);
    builtinTotalNanos +=
        addDurations(builtinTasks, builtinFunctionDurations, builtinFunctionSelfDurations);
  }

  /**
   * Add all new durations to previously collected durations for all functions mapped to tasks.
   * @return The sum of the execution times of all {@link Task} values in the map.
   */
  private static long addDurations(
      Multimap<String, Task> functionTasks,
      Map<String, LongArrayList> durationsMap,
      Map<String, LongArrayList> selfDurationsMap) {
    long totalTime = 0;
    for (Entry<String, Collection<Task>> entry : functionTasks.asMap().entrySet()) {
      String function = entry.getKey();
      Collection<Task> tasks = entry.getValue();
      LongArrayList durations;
      LongArrayList selfDurations;
      if (durationsMap.containsKey(function)) {
        durations = durationsMap.get(function);
        selfDurations = selfDurationsMap.get(function);
      } else {
        durations = new LongArrayList(tasks.size());
        selfDurations = new LongArrayList(tasks.size());
        durationsMap.put(function, durations);
        selfDurationsMap.put(function, selfDurations);
      }
      totalTime += addDurations(tasks, durations, selfDurations);
    }
    return totalTime;
  }

  /**
   * Add all durations and self-times of the given function to the maps.
   * @return The sum of the execution times of all {@link Task} values in the collection.
   */
  private static long addDurations(
      Collection<Task> tasks, LongArrayList durations, LongArrayList selfDurations) {
    long totalTime = 0;
    durations.ensureCapacity(durations.size() + tasks.size());
    selfDurations.ensureCapacity(selfDurations.size() + tasks.size());
    for (Task task : tasks) {
      durations.add(task.durationNanos);
      selfDurations.add(task.durationNanos - task.getInheritedDuration());
      totalTime += task.durationNanos;
    }
    return totalTime;
  }

  /**
   * Build a Map of {@link TasksStatistics} from the given duration maps.
   */
  private static Map<String, TasksStatistics> buildTasksStatistics(
      final Map<String, LongArrayList> durationsMap) {
    return Maps.transformEntries(
        durationsMap,
        new EntryTransformer<String, LongArrayList, TasksStatistics>() {
          @Override
          public TasksStatistics transformEntry(String function, LongArrayList durations) {
            return TasksStatistics.create(function, durations);
          }
        });
  }
}
