// 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);
    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.scopedOutput);

  final Uri serviceUri;
  final IOSink out;
  final Duration timeout;
  final bool waitPaused;
  final bool resume;
  final bool includeDart;
  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('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);
  }

  void 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,
    scopedOutput.toSet(),
  );
}
