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

Future<Map> getAllCoverage(Observatory observatory) {
  return observatory.getIsolates()
      .then((isolates) => isolates.map((i) => i.getCoverage()))
      .then(Future.wait)
      .then((responses) {
        // flatten response lists
        var allCoverage = responses.expand((it) => it).toList();
        return {
          'type': 'CodeCoverage',
          'coverage': allCoverage,
        };
    });
}

Future unpinIsolates(Observatory observatory) {
  return observatory.getIsolates()
      .then((isolates) => isolates.map((i) => i.unpin()))
      .then(Future.wait);
}

Future<Observatory> connect(String host, String port) {
  return http.get('http://$host:$port/json').then((resp) {
    var json = JSON.decode(resp.body);
    if (json is List) {
      return Observatory.connectOverDevtools(host, port);
    }
    return Observatory.connect(host, port);
  });
}

void main(List<String> arguments) {
  var options = parseArgs(arguments);
  var watch = new Stopwatch()..start();
  new Timer.periodic(new Duration(milliseconds: 200), (timer) {
    connect(options.host, options.port).then((observatory) {
      timer.cancel();
      getAllCoverage(observatory)
          .then(JSON.encode)
          .then(options.out.write)
          .then((_) => options.out.close())
          .then((_) => options.unpin ? unpinIsolates(observatory) : null)
          .then((_) => observatory.close());
    }, onError: (_) {
      if ((options.timeout != null) && (watch.elapsed > options.timeout)) {
        var timeout = options.timeout.inSeconds;
        print('Failed to collect coverage within ${timeout}s');
        exit(1);
      }
    });
  });
}

class Options {
  final String host;
  final String port;
  final IOSink out;
  final Duration timeout;
  final bool unpin;
  Options(this.host, this.port, this.out, this.timeout, this.unpin);
}

Options parseArgs(List<String> arguments) {
  var parser = new ArgParser();

  parser.addOption('host', abbr: 'H', defaultsTo: '127.0.0.1',
      help: 'remote VM host');
  parser.addOption('port', abbr: 'p', help: 'remote VM port');
  parser.addOption('out', abbr: 'o', defaultsTo: 'stdout',
      help: 'output: may be file or stdout');
  parser.addOption('connect-timeout', abbr: 't',
      help: 'connect timeout in seconds');
  parser.addFlag('unpin-isolates', abbr: 'u', defaultsTo: false,
      help: 'unpin all isolates on exit');
  parser.addFlag('help', abbr: 'h', negatable: false,
      help: 'show this help');
  var args = parser.parse(arguments);

  printUsage() {
    print('Usage: dart collect_coverage.dart --port=NNNN [OPTION...]\n');
    print(parser.getUsage());
  }

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

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

  if (args['port'] == null) fail('port not specified');

  var out;
  if (args['out'] == 'stdout') {
    out = stdout;
  } else {
    var outfile = new File(args['out'])
        ..createSync(recursive: true);
    out = outfile.openWrite();
  }
  var timeout = (args['connect-timeout'] == null) ? null
      : new Duration(seconds: int.parse(args['connect-timeout']));
  return new Options(args['host'], args['port'], out, timeout,
      args['unpin-isolates']);
}
