// 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:async';
import 'dart:convert';
import 'dart:io';

import 'package:args/args.dart';
import 'package:path/path.dart' as path;
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';

  FutureOr<shelf.Response> _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(jsonDecode(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 url = prefix == '' ? 'coverage' : '$prefix/coverage';
  var hook = '''
      self.dartCallInstrumentation = function(id, name) {
        if (!this.traceBuffer) {
          this.traceBuffer = [];
        }
        var buffer = this.traceBuffer;
        if (buffer.length == 0) {
          window.setTimeout(function() {
            var xhr = new XMLHttpRequest();
            xhr.open("POST", "/$url");
              xhr.send(JSON.stringify(buffer));
              buffer.length = 0;
            }, 1000);
        }
        buffer.push([id, name]);
     };
     ''';
  return '$hook$code';
}

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