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

/// Collects the configurations for all status files in the 'tests' folder that
/// mention one of the test names given as argument.

import 'dart:async';
import 'dart:math' hide log;
import 'dart:io';

import 'package:args/args.dart';
import 'package:gardening/src/util.dart';

void help(ArgParser argParser) {
  print('Prints all status-file entries for the given tests.');
  print('The test-names must be a substring (or full match) of the lines in ');
  print('the status file. They can not be fully qualified');
  print('Usage: status_summary [options] <test-name1> [<test-name2> ...]');
  print('where options are:');
  print(argParser.usage);
}

Future main(List<String> args) async {
  ArgParser argParser = createArgParser();
  ArgResults argResults = argParser.parse(args);
  processArgResults(argResults);
  if (argResults.rest.length == 0 || argResults['help']) {
    help(argParser);
    if (argResults['help']) return;
    exit(1);
  }
  int maxStatusWidth = 0;
  int maxConfigWidth = 0;

  Directory testDirectory = findTestDirectory('tests');
  List<Uri> statusFiles = await findStatusFiles(testDirectory);
  Directory pkgDirectory = findTestDirectory('pkg');
  statusFiles.addAll(await findStatusFiles(pkgDirectory));
  Directory runtimeDirectory = findTestDirectory('runtime');
  statusFiles.addAll(await findStatusFiles(runtimeDirectory));
  Map<String, List<StatusFile>> statusMap = <String, List<StatusFile>>{};
  for (Uri uri in statusFiles) {
    Map<String, StatusFile> currentMap = <String, StatusFile>{};
    log('Scanning $uri');
    String currentConfig = '';
    for (String line in new File.fromUri(uri).readAsLinesSync()) {
      if (line.startsWith('[')) {
        currentConfig = line;
      } else {
        int colonIndex = line.indexOf(':');
        if (colonIndex != -1) {
          String testName = line.substring(0, colonIndex).trim();
          int hashIndex = line.indexOf('#', colonIndex + 1);
          String status;
          String comment;
          if (hashIndex != -1) {
            status = line.substring(colonIndex + 1, hashIndex).trim();
            comment = line.substring(hashIndex + 1).trim();
          } else {
            status = line.substring(colonIndex + 1).trim();
            comment = '';
          }

          for (String arg in argResults.rest) {
            if (testName.contains(arg) || arg.contains(testName)) {
              StatusFile statusFile =
                  currentMap.putIfAbsent(testName, () => new StatusFile(uri));
              statusFile.entries
                  .add(new StatusEntry(currentConfig, status, comment));

              maxStatusWidth = max(maxStatusWidth, status.length);
              maxConfigWidth = max(maxConfigWidth, currentConfig.length);
            }
          }
        }
      }
    }
    currentMap.forEach((String testName, StatusFile configFile) {
      statusMap.putIfAbsent(testName, () => <StatusFile>[]).add(configFile);
    });
  }
  statusMap.forEach((String arg, List<StatusFile> statusFiles) {
    print('$arg');
    for (StatusFile statusFile in statusFiles) {
      print('  ${statusFile.uri}');
      statusFile.entries.forEach((StatusEntry entry) {
        print('    ${padRight(entry.status, maxStatusWidth)}'
            ' ${padRight(entry.config, maxConfigWidth)} ${entry.comment}');
      });
    }
  });
}

/// Finds the test directory.
///
/// First looks at a test-directory that is relative to the current
Directory findTestDirectory(String directoryName) {
  var directory = new Directory(directoryName);
  if (directory.existsSync()) return directory;
  return new Directory.fromUri(
      Platform.script.resolve("../../../$directoryName"));
}

/// Returns the [Uri]s for all `.status` files in [path] and subdirectories.
Future<List<Uri>> findStatusFiles(Directory testDirectory) async {
  List<Uri> statusFiles = <Uri>[];
  await for (FileSystemEntity entity in testDirectory.list(recursive: true)) {
    if (entity.path.endsWith('.status')) {
      statusFiles.add(entity.uri);
    }
  }
  return statusFiles;
}

/// The entries collected for a single status file.
class StatusFile {
  final Uri uri;
  final List<StatusEntry> entries = <StatusEntry>[];

  StatusFile(this.uri);
}

/// A single entry in a status file.
class StatusEntry {
  /// The preceding config line, if any. I.e. the `[...]` line that contained
  /// this entry, or the empty string otherwise.
  final String config;

  /// The status of the entry, e.g. `Pass, Slow`.
  final String status;

  /// The comment after the status, if any.
  final String comment;

  StatusEntry(this.config, this.status, this.comment);

  String toString() => '$status $config $comment';
}
