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

import 'usage_exception.dart';

class CoverageLogServerCommand extends Command<void> with PrintUsageException {
  @override
  final String name = 'coverage_server';
  @override
  final String description = 'Server to gather code coverage data';

  CoverageLogServerCommand() {
    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')
      ..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: _defaultOutTemplate);
  }

  @override
  void run() async {
    final args = argResults!;
    if (args.rest.isEmpty) {
      usageException('Missing arguments: <dart2js-out-file> [<html-file>]');
    }

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

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

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 => JsonEncoder.withIndent(' ').convert(data);

  _Server(this.hostname, this.port, this.jsPath, this.htmlPath, this.outPath,
      String prefix)
      : jsCode = _adjustRequestUrl(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 File(htmlPath!).readAsString();
      return shelf.Response.ok(contents, headers: _htmlHeaders);
    }

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

    // 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 shelf.Response.ok(_serializedData, headers: _textHeaders);
      }

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

    // Any other request is not supported.
    return 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 Future.delayed(Duration(seconds: 3));
      await 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 _htmlHeaders = {'content-type': 'text/html'};
const _jsHeaders = {'content-type': 'text/javascript'};
const _textHeaders = {'content-type': 'text/plain'};
