/*
 *  This file is part of the Jikes RVM project (http://jikesrvm.org).
 *
 *  This file is licensed to You under the Eclipse Public License (EPL);
 *  You may not use this file except in compliance with the License. You
 *  may obtain a copy of the License at
 *
 *      http://www.opensource.org/licenses/eclipse-1.0.php
 *
 *  See the COPYRIGHT.txt file distributed with this work for information
 *  regarding copyright ownership.
 */
package org.mmtk.utility.statistics;

import org.mmtk.plan.Plan;
import org.mmtk.utility.Log;
import org.mmtk.utility.options.Options;
import org.mmtk.utility.options.PrintPhaseStats;
import org.mmtk.utility.options.XmlStats;

import org.mmtk.vm.VM;

import org.vmmagic.pragma.*;

/**
 * This class implements basic statistics functionality
 */
@Uninterruptible public class Stats {

  /****************************************************************************
   *
   * Class variables
   */

  public static final boolean GATHER_MARK_CONS_STATS = false;

  /** Maximum number of gc/mutator phases that can be counted */
  static final int MAX_PHASES = 1 << 12;
  /** Maximum number of counters that can be in operation */
  static final int MAX_COUNTERS = 100;

  private static int counters = 0;
  private static Counter[] counter;
  static int phase = 0;
  private static int gcCount = 0;
  static boolean gatheringStats = false;
  static boolean exceededPhaseLimit = false;

  /****************************************************************************
   *
   * Initialization
   */

  /**
   * Class initializer.  This is executed <i>prior</i> to bootstrap
   * (i.e. at "build" time).  This is where key <i>global</i>
   * instances are allocated.  These instances will be incorporated
   * into the boot image by the build process.
   */
  static {
    counter = new Counter[MAX_COUNTERS];
    Options.printPhaseStats = new PrintPhaseStats();
    Options.xmlStats = new XmlStats();
  }

  /**
   * Add a new counter to the set of managed counters.
   *
   * @param ctr The counter to be added.
   */
  @Interruptible
  static void newCounter(Counter ctr) {
    if (counters < (MAX_COUNTERS - 1)) {
      counter[counters++] = ctr;
    } else {
      Log.writeln("Warning: number of stats counters exceeds maximum");
    }
  }

  /**
   * Start a new GC phase.  This means notifying each counter of the
   * phase change.
   */
  public static void startGC() {
    gcCount++;
    if (!gatheringStats) return;
    if (phase < MAX_PHASES - 1) {
      for (int c = 0; c < counters; c++) {
        counter[c].phaseChange(phase);
      }
      phase++;
    } else if (!exceededPhaseLimit) {
      Log.writeln("Warning: number of GC phases exceeds MAX_PHASES");
      exceededPhaseLimit = true;
    }
  }

  /**
   * End a GC phase.  This means notifying each counter of the phase
   * change.
   */
  public static void endGC() {
    if (!gatheringStats) return;
    if (phase < MAX_PHASES - 1) {
      for (int c = 0; c < counters; c++) {
        counter[c].phaseChange(phase);
      }
      phase++;
    } else if (!exceededPhaseLimit) {
      Log.writeln("Warning: number of GC phases exceeds MAX_PHASES");
      exceededPhaseLimit = true;
    }
  }

  /**
   * Start all implicitly started counters (i.e. those for whom
   * <code>start == true</code>).
   */
  public static void startAll() {
    if (gatheringStats) {
      Log.writeln("Error: calling Stats.startAll() while stats running");
      Log.writeln("       verbosity > 0 and the harness mechanism may be conflicitng");
      if (VM.VERIFY_ASSERTIONS) VM.assertions._assert(false);
    }
    gatheringStats = true;
    for (int c = 0; c < counters; c++) {
      if (counter[c].getStart())
        counter[c].start();
    }

    if (Options.xmlStats.getValue()) {
      Xml.begin();
      Xml.openTag("mmtk-stats");
      Xml.end();
    }
  }

  /**
   * Stop all counters
   */
  @Interruptible
  public static void stopAll() {
    stopAllCounters();
    Stats.printStats();
    if (Options.xmlStats.getValue()) {
      Xml.begin();
      Xml.closeTag("mmtk-stats");
      Xml.end();
    }
  }

  /**
   * Stop all counters
   */
  private static void stopAllCounters() {
    for (int c = 0; c < counters; c++) {
      if (counter[c].getStart())
        counter[c].stop();
    }
    gatheringStats = false;
  }

  @Interruptible
  public static void printStats() {
    if (exceededPhaseLimit) {
      Log.writeln("Warning: number of GC phases exceeds MAX_PHASES.  Statistics are truncated.");
    }
    if (Options.xmlStats.getValue())
      printStatsXml();
    else
      printStatsPlain();
  }

  /**
   * Print out statistics
   */
  @Interruptible
  public static void printStatsPlain() {
    if (Options.printPhaseStats.getValue())
      printPhases();
    printTotals();
  }

  /**
   * Print out statistics totals
   */
  @Interruptible
  public static void printTotals() {
    Log.writeln("============================ MMTk Statistics Totals ============================");
    printColumnNames();
    Log.write(phase/2); Log.write("\t");
    for (int c = 0; c < counters; c++) {
      if (counter[c].mergePhases()) {
        counter[c].printTotal(); Log.write("\t");
      } else {
        counter[c].printTotal(true); Log.write("\t");
        counter[c].printTotal(false); Log.write("\t");
      }
    }
    Log.writeln();
    Log.write("Total time: ");
    Plan.totalTime.printTotal(); Log.writeln(" ms");
    Log.writeln("------------------------------ End MMTk Statistics -----------------------------");
  }

  /**
   * Print out statistics for each mutator/gc phase
   */
  @Interruptible
  public static void printPhases() {
    Log.writeln("--------------------- MMTk Statistics Per GC/Mutator Phase ---------------------");
    printColumnNames();
    for (int p = 0; p <= phase; p += 2) {
      Log.write((p/2)+1); Log.write("\t");
      for (int c = 0; c < counters; c++) {
        if (counter[c].mergePhases()) {
          counter[c].printCount(p); Log.write("\t");
        } else {
          counter[c].printCount(p); Log.write("\t");
          counter[c].printCount(p+1); Log.write("\t");
        }
      }
      Log.writeln();
    }
  }

  /**
   * Print out statistics column names
   */
  @Interruptible
  private static void printColumnNames() {
    Log.write("GC\t");
    for (int c = 0; c < counters; c++) {
      if (counter[c].mergePhases()) {
        Log.write(counter[c].getName());
        Log.write(counter[c].getColumnSuffix());
        Log.write("\t");
      } else {
        Log.write(counter[c].getName());
        Log.write(counter[c].getColumnSuffix());
        Log.write(".mu\t");
        Log.write(counter[c].getName());
        Log.write(counter[c].getColumnSuffix());
        Log.write(".gc\t");
      }
    }
    Log.writeln();
  }

  /* ****************************************************************
   *
   *              Statistics output in xml format
 */

  /**
   * Print command-line options and statistics in XML format
   */
  @Interruptible
  public static void printStatsXml() {
    Xml.begin();
    Options.set.logXml();
    VM.config.printConfigXml();
    if (Options.printPhaseStats.getValue())
      printPhasesXml();
    printTotalsXml();
    Xml.end();
  }

  private static void openStatXml(String name) {
    Xml.openMinorTag("stat");
    Xml.attribute("name", name);
  }

  private static void closeStatXml() {
    Xml.closeMinorTag();
  }

  enum Phase {
    MUTATOR("mu"), GC("gc"), COMBINED("all");

    private final String name;
    Phase(String name) {
      this.name = name;
    }
    public String toString() { return name; }
  }

  /**
   * Print out statistics totals in Xml format
   */
  @Interruptible
  public static void printTotalsXml() {
    Xml.openTag("mmtk-stats-totals");
    Xml.singleValue("gc", phase/2);
    for (int c = 0; c < counters; c++) {
     if (!counter[c].isComplex())
      if (counter[c].mergePhases()) {
        printTotalXml(counter[c],Phase.COMBINED);
      } else {
        printTotalXml(counter[c],Phase.MUTATOR);
        printTotalXml(counter[c],Phase.GC);
      }
    }
    Xml.singleValue("total-time",Plan.totalTime.getTotalMillis(),"ms");
    Xml.closeTag("mmtk-stats-totals");
  }

  /**
   * Print a single total in an xml tag
   *
   * @param c The counter
   * @param phase The phase
   */
  @Interruptible
  private static void printTotalXml(Counter c, Phase phase) {
    openStatXml(c.getName());
    Xml.attribute("suffix", c.getColumnSuffix());
    Xml.openAttribute("value");
    if (phase == Phase.COMBINED) {
      c.printTotal();
    } else {
      c.printTotal(phase == Phase.MUTATOR);
      Xml.closeAttribute();
      Xml.openAttribute("phase");
      Log.write(phase.toString());
    }
    Xml.closeAttribute();
    closeStatXml();
  }

  /**
   * Print a single phase counter in an xml tag
   *
   * @param c The counter
   * @param p The phase number
   * @param phase The phase (null, "mu" or "gc")
   */
  @Interruptible
  private static void printPhaseStatXml(Counter c, int p, Phase phase) {
    openStatXml(c.getName());
    Xml.attribute("suffix", c.getColumnSuffix());
    Xml.openAttribute("value");
    if (phase == Phase.COMBINED) {
      c.printCount(p);
    } else {
      c.printCount(p);
      Xml.closeAttribute();
      Xml.openAttribute("phase");
      Log.write(phase.name);
   }
    Xml.closeAttribute();
    closeStatXml();
  }

  /**
   * Print out statistics for each mutator/gc phase in Xml format
   */
  @Interruptible
  public static void printPhasesXml() {
    Xml.openTag("mmtk-stats-per-gc");
    for (int p = 0; p <= phase; p += 2) {
      Xml.openTag("phase",false);
      Xml.attribute("gc",(p/2)+1);
      Xml.closeMinorTag();
      for (int c = 0; c < counters; c++) {
       if (!counter[c].isComplex())
        if (counter[c].mergePhases()) {
          printPhaseStatXml(counter[c],p,Phase.COMBINED);
        } else {
          printPhaseStatXml(counter[c],p,Phase.MUTATOR);
          printPhaseStatXml(counter[c],p,Phase.GC);
        }
      }
      Xml.closeTag("phase");
    }
    Xml.closeTag("mmtk-stats-per-gc");
  }

  /** @return The GC count (inclusive of any in-progress GC) */
  public static int gcCount() { return gcCount; }

  /** @return True if currently gathering stats */
  public static boolean gatheringStats() { return gatheringStats; }
}
