// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

package com.google.dart.compiler.metrics;

import java.io.PrintStream;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadMXBean;
import java.util.concurrent.atomic.AtomicLong;

/**
 * Collection of compiler metrics.
 */
public final class CompilerMetrics {
  // TODO: Consider refactoring this class so each subsystem has it own metrics class.

  public static long getCPUTime() {
    return System.currentTimeMillis() * 1000000;
  }
  /**
   * Returns the current thread's CPU time or -1 if this is not supported.
   */
  public static long getThreadTime() {
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    if (threadMXBean.isThreadCpuTimeSupported()) {
      return threadMXBean.getCurrentThreadCpuTime();
    }

    return -1;
  }

  private static double nanoToMillis(long nanoTime) {
    return nanoTime / 1000000.0d;
  }
  private AtomicLong charactersParsed = new AtomicLong();
  private AtomicLong charactersParsedExcludingComments = new AtomicLong();
  private long compileLibrariesTime = 0L;
  private long compileLibrariesTimeStart = 0L;
  private AtomicLong linesParsed = new AtomicLong();
  private AtomicLong linesParsedExcludingComments = new AtomicLong();

  private long milliEndTime = -1;
  private final long milliStartTime;
  
  private long nanoParseWallTime = 0;
  private AtomicLong nanoTotalParseTime = new AtomicLong();
  private long nativeLibCharCount;

  // Parser metrics
  private AtomicLong unitsParsed = new AtomicLong();

  private long updateAndResolveTime = 0L;

  // Timing metrics for complete stages
  private long updateAndResolveTimeStart = 0L;

  public CompilerMetrics() {
    this.milliStartTime = System.currentTimeMillis();
  }

  /**
   * Accumulate more parsing time. TODO: Once the parser gets cleaned up we should be able to
   * integrate this with unit parsed.
   */
  public void addParseTimeNano(long nanoTotalParseTime) {
    this.nanoTotalParseTime.addAndGet(nanoTotalParseTime);
  }

  public void addParseWallTimeNano( long nanoWallParseTime) {
    this.nanoParseWallTime = nanoWallParseTime;
  }

  public void done() {
    if (milliEndTime == -1) {
      milliEndTime = System.currentTimeMillis();
    }
  }

  public void endCompileLibrariesTime() {
    compileLibrariesTime = System.currentTimeMillis() - compileLibrariesTimeStart;
  }

  public void endUpdateAndResolveTime() {
    updateAndResolveTime = System.currentTimeMillis() - updateAndResolveTimeStart;
  }

  public long getCompileLibrariesTime() {
    return compileLibrariesTime;
  }

  public long getJSNativeLibCharSize() {
    return nativeLibCharCount;
  }

  public double getLinesPerMS() {
    return getNumLinesParsed() / getTotalCompilationTime();
  }

  public double getNonCommentLinesPerMS() {
    return getNumNonCommentLines() / getTotalCompilationTime();
  }

  public long getNumCharsParsed() {
    return charactersParsed.get();
  }

  public long getNumLinesParsed() {
    return linesParsed.get();
  }

  public long getNumNonCommentChars() {
    return charactersParsedExcludingComments.get();
  }

  public long getNumNonCommentLines() {
    return linesParsedExcludingComments.get();
  }

  public double getNumUnitsParsed() {
    return unitsParsed.get();
  }

  public double getParseTime() {
    return nanoToMillis(nanoTotalParseTime.get());
  }

  public double getParseWallTime() {
    return nanoToMillis(nanoParseWallTime);
  }

  public double getPercentCharsConsumedByNativeLibraries() {
    return (getJSNativeLibCharSize() / getNumCharsParsed()) * 100d;
  }

  public double getPercentTimeParsing() {
    return getParseTime() / getTotalCompilationTime();
  }
  
  public double getTimeSpentPerUnit() {
    if (getNumUnitsParsed() == 0) {
      return 0;
    }
    return getTotalCompilationTime() / getNumUnitsParsed();
  }
  
  public double getTotalCompilationTime() {
    return milliEndTime - milliStartTime;
  }
  
  public long getUpdateAndResolveTime() {
    return updateAndResolveTime;
  }
  
  public void startCompileLibrariesTime() {
    compileLibrariesTimeStart = System.currentTimeMillis();
  }
  
  public void startUpdateAndResolveTime() {
    updateAndResolveTimeStart = System.currentTimeMillis();
  }
  
  public void unitParsed(int charactersParsed, int charactersParsedExcludingComments,
      int linesParsed, int linesParsedExcludingComments) {
    this.unitsParsed.incrementAndGet();
    this.charactersParsed.addAndGet(charactersParsed);
    this.charactersParsedExcludingComments.addAndGet(charactersParsedExcludingComments);
    this.linesParsed.addAndGet(linesParsed);
    this.linesParsedExcludingComments.addAndGet(linesParsedExcludingComments);
  }
  
  /**
   * Writes the metrics to the {@link PrintStream}.
   */
  public void write(PrintStream out) {
    /* This is mainly for the metrics system.  Units should be encoded in
     * the label name and end up as the benchmark names.
     */
    done();
    out.format("Compile-time-total-ms          : %1$.2f%n", getTotalCompilationTime());
    out.format("# Update-and-resolve-time-ms     : %d\n", getUpdateAndResolveTime());
    out.format("# Compile-libraries-time-ms      : %d\n", getCompileLibrariesTime());
    out.println("# Compile-time-unit-average-ms  : " + getTimeSpentPerUnit());
    out.format("# Parse-wall-time-ms             : %1$.2f%n", getParseWallTime());
    out.format("# Parse-time-ms                  : %1$.2f%n", getParseTime());
    out.println("# Parsed-units                   : " + getNumUnitsParsed());
    out.println("# Parsed-src-chars               : " + getNumCharsParsed());
    out.println("# Parsed-src-lines               : " + getNumLinesParsed());
    out.println("# Parsed-code-chars              : " + getNumNonCommentChars());
    out.println("# Parsed-code-lines              : " + getNumNonCommentLines());
    double jsNativeLibCharSize = (getJSNativeLibCharSize() == -1) ? 0 : getJSNativeLibCharSize();
    out.println("# Output-js-native-lib-chars     : " + jsNativeLibCharSize );
    out.println("# Processed-total-lines-ms       : " + getLinesPerMS());
    out.println("# Processed-code-lines-ms        : " + getNonCommentLinesPerMS());
    out.println("# Ratio-parsing-compile-percent  : " + getPercentTimeParsing() * 100);
  }
}
