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

/// A tool to gather coverage data from an app generated with dart2js. This
/// depends on code that has been landed in the bleeding_edge version of dart2js
/// and that we expect to become publicly visible in version 0.13.0 of the Dart
/// SDK).
///
/// This tool starts a server that answers to mainly 2 requests:
///    * a GET request to retrieve the application
///    * POST requests to record coverage data.
///
/// It is intended to be used as follows:
///    * generate an app by running dart2js with the environment value
///      -DtraceCalls=post provided to the vm, and the --dump-info
///      flag provided to dart2js.
///    * start this server, and proxy requests from your normal frontend
///      server to this one.
library dart2js_info.bin.coverage_log_server;

import 'dart:convert';
import 'dart:io';
import 'dart:async';
import 'package:path/path.dart' as path;
import 'package:args/args.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf;

const _DEFAULT_OUT_TEMPLATE = '<dart2js-out-file>.coverage.json';

main(argv) async {
  var parser = new ArgParser()
    ..addOption('port', abbr: 'p', help: 'port number', defaultsTo: "8080")
    ..addOption('host',
        help: 'host name (use 0.0.0.0 for all interfaces)',
        defaultsTo: 'localhost')
    ..addFlag('help',
        abbr: 'h', help: 'show this help message', negatable: false)
    ..addOption('uri-prefix',
        help: 'uri path prefix that will hit this server. This will be injected'
            ' into the .js file',
        defaultsTo: '')
    ..addOption('out',
        abbr: 'o', help: 'output log file', defaultsTo: _DEFAULT_OUT_TEMPLATE);
  var args = parser.parse(argv);
  if (args['help'] == true || args.rest.isEmpty) {
    print('usage: dart coverage_logging.dart [options] '
        '<dart2js-out-file> [<html-file>]');
    print(parser.usage);
    exit(1);
  }

  var jsPath = args.rest[0];
  var htmlPath = null;
  if (args.rest.length > 1) {
    htmlPath = args.rest[1];
  }
  var outPath = args['out'];
  if (outPath == _DEFAULT_OUT_TEMPLATE) outPath = '$jsPath.coverage.json';
  var server = new _Server(args['host'], int.parse(args['port']), jsPath,
      htmlPath, outPath, args['uri-prefix']);
  await server.run();
}

class _Server {
  /// Server hostname, typically `localhost`,  but can be `0.0.0.0`.
  final String hostname;

  /// Port the server will listen to.
  final int port;

  /// JS file (previously generated by dart2js) to serve.
  final String jsPath;

  /// HTML file to serve, if any.
  final String htmlPath;

  /// Contents of jsPath, adjusted to use the appropriate server url.
  String jsCode;

  /// Location where we'll dump the coverage data.
  final String outPath;

  /// Uri prefix used on all requests to this server. This will be injected into
  /// the .js file.
  final String prefix;

  // TODO(sigmund): add support to load also simple HTML files to test small
  // simple apps.

  /// Data received so far. The data is just an array of pairs, showing the
  /// hashCode and name of the element used. This can be later cross-checked
  /// against dump-info data.
  Map data = {};

  String get _serializedData => new JsonEncoder.withIndent(' ').convert(data);

  _Server(this.hostname, this.port, String jsPath, this.htmlPath, this.outPath,
      String prefix)
      : jsPath = jsPath,
        jsCode = _adjustRequestUrl(new File(jsPath).readAsStringSync(), prefix),
        prefix = _normalize(prefix);

  run() async {
    await shelf.serve(_handler, hostname, port);
    var urlBase = "http://$hostname:$port${prefix == '' ? '/' : '/$prefix/'}";
    var htmlFilename = htmlPath == null ? '' : path.basename(htmlPath);
    print("Server is listening\n"
        "  - html page: $urlBase$htmlFilename\n"
        "  - js code: $urlBase${path.basename(jsPath)}\n"
        "  - coverage reporting: ${urlBase}coverage\n");
  }

  _expectedPath(String tail) => prefix == '' ? tail : '$prefix/$tail';

  _handler(shelf.Request request) async {
    var urlPath = request.url.path;
    print('received request: $urlPath');
    var baseJsName = path.basename(jsPath);
    var baseHtmlName = htmlPath == null ? '' : path.basename(htmlPath);

    // Serve an HTML file at the default prefix, or a path matching the HTML
    // file name
    if (urlPath == prefix ||
        urlPath == '$prefix/' ||
        urlPath == _expectedPath(baseHtmlName)) {
      var contents = htmlPath == null
          ? '<html><script src="$baseJsName"></script>'
          : await new File(htmlPath).readAsString();
      return new shelf.Response.ok(contents, headers: HTML_HEADERS);
    }

    if (urlPath == _expectedPath(baseJsName)) {
      return new shelf.Response.ok(jsCode, headers: JS_HEADERS);
    }

    // Handle POST requests to record coverage data, and GET requests to display
    // the currently coverage resutls.
    if (urlPath == _expectedPath('coverage')) {
      if (request.method == 'GET') {
        return new shelf.Response.ok(_serializedData, headers: TEXT_HEADERS);
      }

      if (request.method == 'POST') {
        _record(JSON.decode(await request.readAsString()));
        return new shelf.Response.ok("Thanks!");
      }
    }

    // Any other request is not supported.
    return new shelf.Response.notFound('Not found: "$urlPath"');
  }

  _record(List entries) {
    for (var entry in entries) {
      var id = entry[0];
      data.putIfAbsent('$id', () => {'name': entry[1], 'count': 0});
      data['$id']['count']++;
    }
    _enqueueSave();
  }

  bool _savePending = false;
  int _total = 0;
  _enqueueSave() async {
    if (!_savePending) {
      _savePending = true;
      await new Future.delayed(new Duration(seconds: 3));
      await new File(outPath).writeAsString(_serializedData);
      var diff = data.length - _total;
      print(
          diff ? ' - no new element covered' : ' - $diff new elements covered');
      _savePending = false;
      _total = data.length;
    }
  }
}

/// Removes leading and trailing slashes of [uriPath].
_normalize(String uriPath) {
  if (uriPath.startsWith('/')) uriPath = uriPath.substring(1);
  if (uriPath.endsWith('/')) uriPath = uriPath.substring(0, uriPath.length - 1);
  return uriPath;
}

_adjustRequestUrl(String code, String prefix) {
  var newUrl = prefix == '' ? 'coverage' : '$prefix/coverage';
  return code.replaceFirst('"/coverage_uri_to_amend_by_server"',
      '"/$newUrl" /*url-prefix updated!*/');
}

const HTML_HEADERS = const {'content-type': 'text/html'};
const JS_HEADERS = const {'content-type': 'text/javascript'};
const TEXT_HEADERS = const {'content-type': 'text/plain'};
