/*
 * Copyright 2009 Google Inc.
 * 
 * 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.gwt.dev.util;

import com.google.gwt.thirdparty.guava.common.base.Preconditions;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * A counter which records bunch of statistics for frequently occuring 
 * operations. Calculates: count, total time, average time, maximum time 
 * & slow operations. 
 */
public class PerfCounter {
  private static class OperationStats {
    private long count = 0;
    private boolean isCounter = false;
    private long maxTimeNanos = 0;
    private long slowCount = 0;
    private long totalSlowTimeNanos = 0;
    private long totalTimeNanos = 0;
    
    @Override
    public String toString() {
      StringBuilder result = new StringBuilder();
      
      if (!isCounter) {
        result.append(count);
        result.append("/");
        result.append(totalTimeNanos / 1000000000.0);
        result.append("/");
        result.append(totalTimeNanos / 1000000000.0 / count);
        result.append("/");
        result.append(maxTimeNanos / 1000000000.0);
        result.append("/");
        result.append(slowCount);
        result.append("/");
        result.append(totalSlowTimeNanos * 1.0 / totalTimeNanos);
        result.append(" ");
        result.append(
            "(count/total_time/avg_time/max_time/slow_count/slow_ratio)");
      } else {
        result.append(count);
        result.append(" (count)");
      }
      
      return result.toString();
    }
  }

  /**
   * Flag for enabling performance logging.
   */
  private static boolean enabled = 
    Boolean.parseBoolean(System.getProperty("gwt.perfcounters"));
  
  private static final ThreadLocal<Map<String, Long>> operationsStartTime = 
    new ThreadLocal<Map<String,Long>>() {
    @Override
    protected Map<String, Long> initialValue() {
      return new HashMap<String, Long>();
    }
  };
  
  private static final Map<String, OperationStats> operationStats = 
    new HashMap<String, OperationStats>();
  
  /**
   * Record the end of the operation. 
   */
  public static void end(String operation) {
    if (!enabled) {
      return;
    }
    end(operation, 1 * 1000000000 /* 1 sec */);
  }
  
  /**
   * Record the end of the operation. 
   */
  public static void end(String operation, long slowThresholdNano) {
    if (!enabled) {
      return;
    }
    long finishTime = System.nanoTime();
    
    Map<String, Long> startTimes = operationsStartTime.get();
    
    Long startTime;
    
    synchronized (startTimes) {
      startTime = startTimes.remove(operation);
    }
    
    Preconditions.checkNotNull(startTime);

    synchronized (operationStats) {
      OperationStats stats = getStats(operation);
      
      stats.count++;
      long elapsedTime = finishTime - startTime.longValue();
      stats.totalTimeNanos += elapsedTime;
      stats.maxTimeNanos = Math.max(stats.maxTimeNanos, elapsedTime);
      if (elapsedTime > slowThresholdNano) {
        stats.slowCount++;
        stats.totalSlowTimeNanos += elapsedTime;
      }
    }
  }

  /**
   * Increment counter. 
   */
  public static void inc(String operation) {
    synchronized (operationStats) {
      OperationStats stats = getStats(operation);
      stats.count++;
      stats.isCounter = true;
    }
  }

  public static void print() {
    if (!enabled) {
      return;
    }
    System.out.println("------------- Perf Counters -------------");
    synchronized (operationStats) {
      List<String> keys = new ArrayList<String>(operationStats.keySet());
      Collections.sort(keys);
      for (String operation : keys) {
        System.out.println(operation + ": " + operationStats.get(operation));
      }
    }
    System.out.println("-----------------------------------------");
  }
  
  /**
   * Start operation.
   */
  public static void start(String operation) {
    if (!enabled) {
      return;
    }
    Map<String, Long> startTimes = operationsStartTime.get();
    
    synchronized (startTimes) {
      Preconditions.checkState(!startTimes.containsKey(operation));
      long startTime = System.nanoTime();
      startTimes.put(operation, new Long(startTime));
    }
  }

  private static OperationStats getStats(String operation) {
    OperationStats stats = operationStats.get(operation);
    if (stats == null) {
      stats = new OperationStats();
      operationStats.put(operation, stats);
    }
    return stats;
  }
}
