// Copyright (c) 2013, 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:io';

import 'package:args/args.dart';
import 'package:coverage/coverage.dart';
import 'package:path/path.dart' as p;

/// [Environment] stores gathered arguments information.
class Environment {
  Environment({
    required this.baseDirectory,
    required this.bazel,
    required this.bazelWorkspace,
    required this.checkIgnore,
    required this.input,
    required this.lcov,
    required this.output,
    required this.packagesPath,
    required this.prettyPrint,
    required this.prettyPrintFunc,
    required this.reportOn,
    required this.sdkRoot,
    required this.verbose,
    required this.workers,
  });

  String? baseDirectory;
  bool bazel;
  String bazelWorkspace;
  bool checkIgnore;
  String input;
  bool lcov;
  IOSink output;
  String? packagesPath;
  bool prettyPrint;
  bool prettyPrintFunc;
  List<String>? reportOn;
  String? sdkRoot;
  bool verbose;
  int workers;
}

Future<Null> main(List<String> arguments) async {
  final env = parseArgs(arguments);

  final files = filesToProcess(env.input);
  if (env.verbose) {
    print('Environment:');
    print('  # files: ${files.length}');
    print('  # workers: ${env.workers}');
    print('  sdk-root: ${env.sdkRoot}');
    print('  package-spec: ${env.packagesPath}');
    print('  report-on: ${env.reportOn}');
    print('  check-ignore: ${env.checkIgnore}');
  }

  final clock = Stopwatch()..start();
  final hitmap = await parseCoverage(
    files,
    env.workers,
    checkIgnoredLines: env.checkIgnore,
    packagesPath: env.packagesPath,
  );

  // All workers are done. Process the data.
  if (env.verbose) {
    print('Done creating global hitmap. Took ${clock.elapsedMilliseconds} ms.');
  }

  String output;
  final resolver = env.bazel
      ? BazelResolver(workspacePath: env.bazelWorkspace)
      : Resolver(packagesPath: env.packagesPath, sdkRoot: env.sdkRoot);
  final loader = Loader();
  if (env.prettyPrint || env.prettyPrintFunc) {
    output = await PrettyPrintFormatter(resolver, loader,
            reportOn: env.reportOn, reportFuncs: env.prettyPrintFunc)
        .format(hitmap);
  } else {
    assert(env.lcov);
    output = await LcovFormatter(resolver,
            reportOn: env.reportOn, basePath: env.baseDirectory)
        .format(hitmap);
  }

  env.output.write(output);
  await env.output.flush();
  if (env.verbose) {
    print('Done flushing output. Took ${clock.elapsedMilliseconds} ms.');
  }

  if (env.verbose) {
    if (resolver.failed.isNotEmpty) {
      print('Failed to resolve:');
      for (var error in resolver.failed.toSet()) {
        print('  $error');
      }
    }
    if (loader.failed.isNotEmpty) {
      print('Failed to load:');
      for (var error in loader.failed.toSet()) {
        print('  $error');
      }
    }
  }
  await env.output.close();
}

/// Checks the validity of the provided arguments. Does not initialize actual
/// processing.
Environment parseArgs(List<String> arguments) {
  final parser = ArgParser();

  parser.addOption('sdk-root', abbr: 's', help: 'path to the SDK root');
  parser.addOption('packages', help: 'path to the package spec file');
  parser.addOption('in', abbr: 'i', help: 'input(s): may be file or directory');
  parser.addOption('out',
      abbr: 'o', defaultsTo: 'stdout', help: 'output: may be file or stdout');
  parser.addMultiOption('report-on',
      help: 'which directories or files to report coverage on');
  parser.addOption('workers',
      abbr: 'j', defaultsTo: '1', help: 'number of workers');
  parser.addOption('bazel-workspace',
      defaultsTo: '', help: 'Bazel workspace directory');
  parser.addOption('base-directory',
      abbr: 'b',
      help: 'the base directory relative to which source paths are output');
  parser.addFlag('bazel',
      defaultsTo: false, help: 'use Bazel-style path resolution');
  parser.addFlag('pretty-print',
      abbr: 'r',
      negatable: false,
      help: 'convert line coverage data to pretty print format');
  parser.addFlag('pretty-print-func',
      abbr: 'f',
      negatable: false,
      help: 'convert function coverage data to pretty print format');
  parser.addFlag('lcov',
      abbr: 'l',
      negatable: false,
      help: 'convert coverage data to lcov format');
  parser.addFlag('verbose',
      abbr: 'v', negatable: false, help: 'verbose output');
  parser.addFlag(
    'check-ignore',
    abbr: 'c',
    negatable: false,
    help: 'check for coverage ignore comments.'
        ' Not supported in web coverage.',
  );
  parser.addFlag('help', abbr: 'h', negatable: false, help: 'show this help');

  final args = parser.parse(arguments);

  void printUsage() {
    print('Usage: dart format_coverage.dart [OPTION...]\n');
    print(parser.usage);
  }

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

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

  var sdkRoot = args['sdk-root'] as String?;
  if (sdkRoot != null) {
    sdkRoot = p.normalize(p.join(p.absolute(sdkRoot), 'lib'));
    if (!FileSystemEntity.isDirectorySync(sdkRoot)) {
      fail('Provided SDK root "${args["sdk-root"]}" is not a valid SDK '
          'top-level directory');
    }
  }

  final packagesPath = args['packages'] as String?;
  if (packagesPath != null) {
    if (!FileSystemEntity.isFileSync(packagesPath)) {
      fail('Package spec "${args["packages"]}" not found, or not a file.');
    }
  }

  if (args['in'] == null) fail('No input files given.');
  final input = p.absolute(p.normalize(args['in'] as String));
  if (!FileSystemEntity.isDirectorySync(input) &&
      !FileSystemEntity.isFileSync(input)) {
    fail('Provided input "${args["in"]}" is neither a directory nor a file.');
  }

  IOSink output;
  if (args['out'] == 'stdout') {
    output = stdout;
  } else {
    final outpath = p.absolute(p.normalize(args['out'] as String));
    final outfile = File(outpath)..createSync(recursive: true);
    output = outfile.openWrite();
  }

  final reportOnRaw = args['report-on'] as List<String>;
  final reportOn = reportOnRaw.isNotEmpty ? reportOnRaw : null;

  final bazel = args['bazel'] as bool;
  final bazelWorkspace = args['bazel-workspace'] as String;
  if (bazelWorkspace.isNotEmpty && !bazel) {
    stderr.writeln('warning: ignoring --bazel-workspace: --bazel not set');
  }

  String? baseDirectory;
  if (args['base-directory'] != null) {
    baseDirectory = p.absolute(args['base-directory'] as String);
  }

  final lcov = args['lcov'] as bool;
  var prettyPrint = args['pretty-print'] as bool;
  final prettyPrintFunc = args['pretty-print-func'] as bool;
  if ((prettyPrint ? 1 : 0) + (prettyPrintFunc ? 1 : 0) + (lcov ? 1 : 0) > 1) {
    fail('Choose one of the pretty-print modes or lcov output');
  }

  // Use pretty-print either explicitly or by default.
  if (!lcov && !prettyPrintFunc) prettyPrint = true;

  int workers;
  try {
    workers = int.parse('${args["workers"]}');
  } catch (e) {
    fail('Invalid worker count: $e');
  }

  final checkIgnore = args['check-ignore'] as bool;
  final verbose = args['verbose'] as bool;
  return Environment(
      baseDirectory: baseDirectory,
      bazel: bazel,
      bazelWorkspace: bazelWorkspace,
      checkIgnore: checkIgnore,
      input: input,
      lcov: lcov,
      output: output,
      packagesPath: packagesPath,
      prettyPrint: prettyPrint,
      prettyPrintFunc: prettyPrintFunc,
      reportOn: reportOn,
      sdkRoot: sdkRoot,
      verbose: verbose,
      workers: workers);
}

/// Given an absolute path absPath, this function returns a [List] of files
/// are contained by it if it is a directory, or a [List] containing the file if
/// it is a file.
List<File> filesToProcess(String absPath) {
  if (FileSystemEntity.isDirectorySync(absPath)) {
    return Directory(absPath)
        .listSync(recursive: true)
        .whereType<File>()
        .where((e) => e.path.endsWith('.json'))
        .toList();
  }
  return <File>[File(absPath)];
}
