// 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(List<String> 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 results.
    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 == 0
          ? ' - 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'};
