// 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. */
      new Timer(const Duration(milliseconds: 25),
          () => runBenchmarksHelper(remainingBenchmarks));
    } 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);
    }
  }
}
