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

part of benchmark_lib;

/** Accessors for our Singleton variables. */
BenchmarkSuite get BENCHMARK_SUITE {
  if (BenchmarkSuite._ONLY == null) {
    BenchmarkSuite._ONLY = new BenchmarkSuite._internal();
  }
  return BenchmarkSuite._ONLY;
}

BenchmarkView get BENCHMARK_VIEW {
  if (BenchmarkView._ONLY == null) {
    BenchmarkView._ONLY = new BenchmarkView._internal();
  }
  return BenchmarkView._ONLY;
}

/** The superclass from which all benchmarks inherit from. */
class BenchmarkBase {
  /** Benchmark name. */
  final String name;

  const BenchmarkBase(String name) : this.name = name;

  /**
   * The benchmark code.
   * This function is not used, if both [warmup] and [exercise] are overwritten.
   */
  void run() { }

  /** Runs a short version of the benchmark. By default invokes [run] once. */
  void warmup() {
    run();
  }

  /** Exercices the benchmark. By default invokes [run] 10 times. */
  void exercise() {
    for (int i = 0; i < 10; i++) {
      run();
    }
  }

  /** Not measured setup code executed prior to the benchmark runs. */
  void setup() { }

  /** Not measures teardown code executed after the benchark runs. */
  void teardown() { }

  /**
   * Measures the score for this benchmark by executing it repeately until
   * time minimum has been reached.
   */
  static double measureFor(Function f, int timeMinimum) {
    int time = 0;
    int iter = 0;
    Stopwatch watch = new Stopwatch();
    watch.start();
    int elapsed = 0;
    while (elapsed < timeMinimum || iter < 32) {
      f();
      elapsed = watch.elapsedMilliseconds;
      iter++;
    }
    return (1000.0 * iter) / elapsed;
  }

  /**
   * Measures the score for the benchmark and returns it.
   * We measure iterations / sec (so bigger = better!).
   */
  double measure() {
    setup();
    // Warmup for at least 1000ms. Discard result.
    measureFor(() { this.warmup(); }, 1000);
    // Run the benchmark for at least 1000ms.
    double result = measureFor(() { this.exercise(); }, 1000);
    teardown();
    return result;
  }

  void report() {
    num score = measure();
    Map<String, int> normalizingDict = {'Smoketest': 100};
    score = score / normalizingDict[name];
    BENCHMARK_SUITE.updateIndividualScore(name, score);
  }
}

/** The controller class that runs all of the benchmarks. */
class BenchmarkSuite {
  /** The set of benchmarks that have yet to run. */
  List<Function> benchmarks;
  
  /**
   * The set of scores from the benchmarks that have already run. (Used for
   * calculating the Geometric mean).
   */
  List<num> scores;

  /** The total number of benchmarks we will be running. */
  int totalBenchmarks;

  /** Singleton pattern: There's only one BenchmarkSuite. */
  static BenchmarkSuite _ONLY = null;

  BenchmarkSuite._internal() {
    scores = [];
    benchmarks = [() => Smoketest.main()];
    totalBenchmarks = benchmarks.length;
  }
  
  /** Run all of the benchmarks that we have in our benchmarks list. */
  runBenchmarks() {
    runBenchmarksHelper(benchmarks);
  }
 
   /**
   * Run the remaining benchmarks in our list. We chain the calls providing
   * little breaks for the main page to gain control, so we don't force the 
   * entire page to hang the whole time.
   */
  runBenchmarksHelper(List<Function> remainingBenchmarks) {
    // Remove the last benchmark, and run it.
    var benchmark = remainingBenchmarks.removeLast();
    benchmark();
    if (remainingBenchmarks.length > 0) {
      /* Provide small breaks between each benchmark, so that the browser 
      doesn't get unhappy about long running scripts, and so the user
      can regain control of the UI to kill the page as needed. */
      window.setTimeout(() => runBenchmarksHelper(remainingBenchmarks), 25);
    } else if (remainingBenchmarks.length == 0) {
      // We've run all of the benchmarks. Update the page with the score.
      BENCHMARK_VIEW.setScore(geometricMean(scores));
    }
  }

  /** Store the results of a single benchmark run. */
  updateIndividualScore(String name, num score) {
    scores.add(score); 
    BENCHMARK_VIEW.incrementProgress(name, score, totalBenchmarks);
  }

  /** Computes the geometric mean of a set of numbers. */
  geometricMean(numbers) {
    num log = 0;
    for (num n in numbers) {
      log += Math.log(n);
    }
    return Math.pow(Math.E, log / numbers.length);
  }
}

/** Controls how results are displayed to the user, by updating the HTML. */
class BenchmarkView {

  /** The number of benchmarks that have finished executing. */
  int numCompleted = 0;

  /** Singleton pattern: There's only one BenchmarkSuite. */
  static BenchmarkView _ONLY = null;

  BenchmarkView._internal();

  /** Update the page HTML to show the calculated score. */
  setScore(num score) {
    String newScore = formatScore(score * 100.0);
    Element body = document.queryAll("body")[0];
    body.nodes.add(
        new Element.html("<p id='testResultScore'>Score: $newScore</p>"));
  }
 
  /**
   * Update the page HTML to show how much progress we've made through the 
   * benchmarks.
   */
  incrementProgress(String name, num score, num totalBenchmarks) {
    String newScore = formatScore(score * 100.0);
    numCompleted++;
    // Slightly incorrect (truncating) percentage, but this is just to show
    // the user we're making progress.
    num percentage = 100 * numCompleted ~/ totalBenchmarks;
  }
  
  /** 
   * Rounds the score to have at least three significant digits (hopefully)
   * helping readability of the scores.
   */
  String formatScore(num value) {
    if (value > 100) {
      return value.toStringAsFixed(0);
    } else {
      return value.toStringAsFixed(2);
    }
  }
}
