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

import 'dart:async' show Future;
import 'dart:html';
import 'dart:js' show context, JsObject;

import 'generated/benchmark.pb.dart' as pb;

import 'benchmark.dart' show Profiler;
import 'dashboard_model.dart' show DashboardModel, Table, SelectEvent;
import 'dashboard_view.dart' show DashboardView;
import 'report.dart' show createPlatform, createPackages;
import 'suite.dart' show runSuite;

import '../data/index.dart' as data;

/// Displays a dashboard that can be used to run benchmarks.
Future showDashboard(pb.Suite suite, Element container) async {
  // set up model

  var env = await loadBrowserEnv();
  var reports = await loadReports(suite);

  var defaultReport = new pb.Report()..env = env;
  var model = new DashboardModel(reports, new Table(suite), defaultReport);

  var baseline = chooseBaseline(env, reports);
  if (baseline != null) {
    model = model.withBaseline(baseline);
  }

  var view = new DashboardView();

  Future render(pb.Report report) async {
    report.env = env;
    model = model.withReport(report);
    await window.animationFrame;
    view.render(model);
    await new Future(() => null); // exit to regular timer task
  }

  // Set up the main loop that runs the suite.

  bool running = false;
  void runBenchmarks() {
    if (running) return;
    var profiler = new JsProfiler();
    running = true;
    () async {
      var requests = model.table.selections.toList();
      for (pb.Report report in runSuite(requests, profiler: profiler)) {
        await render(report);
      }
    }().whenComplete(() {
      running = false;
    });
  }

  // set up event handlers

  view.onRunButtonClick.listen((_) => runBenchmarks());
  view.onSelectAllClick.listen((_) {
    model = model.withTable(model.table.withAllSelected());
    view.render(model);
  });
  view.onSelectNoneClick.listen((_) {
    model = model.withTable(model.table.withNoneSelected());
    view.render(model);
  });

  view.onMenuChange.listen((String item) {
    model = model.withBaseline(item);
    view.render(model);
  });

  view.onSelectionChange.listen((SelectEvent e) {
    model = model.withTable(model.table.withSelection(e.item, e.selected));
    view.render(model);
  });

  // show the view

  view.render(model);
  container.children.clear();
  container.append(view.elt);
}

/// Starts and stops the DevTools profiler.
class JsProfiler implements Profiler {
  static JsObject console = context["console"];

  int count = 1;

  startProfile(pb.Request request) {
    var label = "$count-${request.id.name}";
    count++;
    console.callMethod("profile", [label]);
  }

  endProfile(pb.Sample s) {
    console.callMethod("profileEnd");
    print("profile: $s");
  }
}

Future<pb.Env> loadBrowserEnv() async {
  const advice = "Run a VM benchmark to create this file.";
  var pubspecYaml = await _loadDataFile(data.pubspecYamlName, advice: advice);
  var pubspecLock = await _loadDataFile(data.pubspecLockName, advice: advice);
  var hostname = await _loadDataFile(data.hostfileName, advice: advice);

  var platform = createPlatform()
    ..hostname = hostname
    ..userAgent = window.navigator.userAgent;

  return new pb.Env()
    ..page = window.location.pathname
    ..platform = platform
    ..packages = createPackages(pubspecYaml, pubspecLock);
}

/// Loads all the reports saved to benchmark/data.
Future<Map<String, pb.Report>> loadReports(pb.Suite suite) async {
  var out = <String, pb.Report>{};
  // TODO: maybe parallelize?
  for (var name in data.allReportNames) {
    String json =
        await _loadDataFile(name, optional: (name == data.latestVMReportName));
    if (json != null) {
      var report = new pb.Report.fromJson(json);
      if (isCompatibleBaseline(suite, report)) {
        out[name] = report;
      }
    }
  }
  print("loaded ${out.length} reports");
  return out;
}

/// Choose the report to display on the left side for comparison.
/// Returns null if no comparable report is found.
String chooseBaseline(pb.Env env, Map<String, pb.Report> reports) {
  for (var name in reports.keys) {
    var candidate = reports[name];
    if (candidate.env.platform == env.platform) {
      return name;
    }
  }
  return null;
}

/// Returns true if the baseline report used the same benchmarks.
bool isCompatibleBaseline(pb.Suite suite, pb.Report report) {
  for (int i = 0; i < suite.requests.length; i++) {
    if (i >= report.responses.length) {
      return true; // additional benchmarks ok
    }
    var request = suite.requests[i];
    var response = report.responses[i];
    if (request != response.request) return false;
  }
  return true;
}

Future<String> _loadDataFile(String name,
    {bool optional: false, String advice}) async {
  try {
    return await HttpRequest.getString("/data/$name");
  } catch (e) {
    if (optional) return null;
    String error = "File is missing in benchmark/data: $name";
    if (advice != null) {
      error += ". $advice";
    }
    throw error;
  }
}
