// Copyright (c) 2014, 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.

import 'dart:async';
import 'dart:convert' show json;
import 'dart:io';

import 'package:args/args.dart';
import 'package:coverage/src/collect.dart';
import 'package:logging/logging.dart';
import 'package:stack_trace/stack_trace.dart';

Future<Null> main(List<String> arguments) async {
  Logger.root.level = Level.WARNING;
  Logger.root.onRecord.listen((LogRecord rec) {
    print('${rec.level.name}: ${rec.time}: ${rec.message}');
  });

  final options = _parseArgs(arguments);
  await Chain.capture(() async {
    final coverage = await collect(options.serviceUri, options.resume,
        options.waitPaused, options.includeDart, options.scopedOutput,
        timeout: options.timeout, functionCoverage: options.functionCoverage);
    options.out.write(json.encode(coverage));
    await options.out.close();
  }, onError: (dynamic error, Chain chain) {
    stderr.writeln(error);
    stderr.writeln(chain.terse);
    // See http://www.retro11.de/ouxr/211bsd/usr/include/sysexits.h.html
    // EX_SOFTWARE
    exit(70);
  });
}

class Options {
  Options(this.serviceUri, this.out, this.timeout, this.waitPaused, this.resume,
      this.includeDart, this.functionCoverage, this.scopedOutput);

  final Uri serviceUri;
  final IOSink out;
  final Duration? timeout;
  final bool waitPaused;
  final bool resume;
  final bool includeDart;
  final bool functionCoverage;
  final Set<String> scopedOutput;
}

Options _parseArgs(List<String> arguments) {
  final parser = ArgParser()
    ..addOption('host',
        abbr: 'H',
        help: 'remote VM host. DEPRECATED: use --uri',
        defaultsTo: '127.0.0.1')
    ..addOption('port',
        abbr: 'p',
        help: 'remote VM port. DEPRECATED: use --uri',
        defaultsTo: '8181')
    ..addOption('uri', abbr: 'u', help: 'VM observatory service URI')
    ..addOption('out',
        abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout')
    ..addOption('connect-timeout',
        abbr: 't', help: 'connect timeout in seconds')
    ..addMultiOption('scope-output',
        help: 'restrict coverage results so that only scripts that start with '
            'the provided package path are considered')
    ..addFlag('wait-paused',
        abbr: 'w',
        defaultsTo: false,
        help: 'wait for all isolates to be paused before collecting coverage')
    ..addFlag('resume-isolates',
        abbr: 'r', defaultsTo: false, help: 'resume all isolates on exit')
    ..addFlag('include-dart',
        abbr: 'd', defaultsTo: false, help: 'include "dart:" libraries')
    ..addFlag('function-coverage',
        abbr: 'f', defaultsTo: false, help: 'Collect function coverage info')
    ..addFlag('help', abbr: 'h', negatable: false, help: 'show this help');

  final args = parser.parse(arguments);

  void printUsage() {
    print('Usage: dart collect_coverage.dart --uri=http://... [OPTION...]\n');
    print(parser.usage);
  }

  Never fail(String message) {
    print('Error: $message\n');
    printUsage();
    exit(1);
  }

  if (args['help'] as bool) {
    printUsage();
    exit(0);
  }

  Uri serviceUri;
  if (args['uri'] == null) {
    // TODO(cbracken) eliminate --host and --port support when VM defaults to
    // requiring an auth token. Estimated for Dart SDK 1.22.
    serviceUri = Uri.parse('http://${args['host']}:${args['port']}/');
  } else {
    try {
      serviceUri = Uri.parse(args['uri'] as String);
    } on FormatException {
      fail('Invalid service URI specified: ${args['uri']}');
    }
  }

  final scopedOutput = args['scope-output'] as List<String>;
  IOSink out;
  if (args['out'] == 'stdout') {
    out = stdout;
  } else {
    final outfile = File(args['out'] as String)..createSync(recursive: true);
    out = outfile.openWrite();
  }
  final timeout = (args['connect-timeout'] == null)
      ? null
      : Duration(seconds: int.parse(args['connect-timeout'] as String));
  return Options(
    serviceUri,
    out,
    timeout,
    args['wait-paused'] as bool,
    args['resume-isolates'] as bool,
    args['include-dart'] as bool,
    args['function-coverage'] as bool,
    scopedOutput.toSet(),
  );
}
