// Copyright (c) 2015, 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.

library protoc.benchmark.suite;

import 'benchmark.dart';
import 'benchmarks/index.dart' show createBenchmark;
import 'generated/benchmark.pb.dart' as pb;

/// Runs a benchmark suite, returning progress until done.
///
/// [samplesPerBatch] is the number of times a benchmark will be run
/// before going on to the next one. They will be executed round-robin
/// until they're all done.
/// [profiler] if supplied, each request will be profiled once.
Iterable<pb.Report> runSuite(List<pb.Request> requests,
    {samplesPerBatch: 1, Profiler profiler}) sync* {
  // Create a blank report with one response per request.
  var report = new pb.Report()..status = pb.Status.RUNNING;
  for (var request in requests) {
    var r = new pb.Response()..request = request;
    report.responses.add(r);
  }

  // Set up progress reports.
  int sampleCount = 0;
  int totalSamples = 0;
  for (var request in requests) {
    totalSamples += request.samples;
  }
  pb.Report progress() {
    report.message = "Running ($sampleCount/$totalSamples)";
    return report.clone();
  }

  // Send first progress message before starting.
  yield progress();

  var benchmarks = <Benchmark>[];
  for (var r in report.responses) {
    benchmarks.add(createBenchmark(r.request));
  }

  // Collect the requested number of samples.
  while (sampleCount < totalSamples) {
    for (var i = 0; i < benchmarks.length; i++) {
      var b = benchmarks[i];
      var r = report.responses[i];
      int batchSize = r.request.samples - r.samples.length;
      if (batchSize == 0) continue;
      if (batchSize > samplesPerBatch) batchSize = samplesPerBatch;
      var p = r.samples.isEmpty ? profiler : null;
      for (pb.Sample s in b.measure(r.request, batchSize, profiler: p)) {
        r.samples.add(s);
        sampleCount++;
        yield progress();
      }
    }
  }

  // Send final report.
  report.status = pb.Status.DONE;
  report.message = "Done";
  yield report;
}
