import 'dart:io';

/// Generates Dart docs for each package with public libraries and fails on warnings.
Future<void> main(List<String> arguments) async {
  final outputRoot = Directory(_join(_join('doc', 'api'), 'packages'));
  if (await outputRoot.exists()) {
    await outputRoot.delete(recursive: true);
  }
  await outputRoot.create(recursive: true);

  final packages = Directory('packages')
      .listSync()
      .whereType<Directory>()
      .where((directory) {
    return File(_join(directory.path, 'pubspec.yaml')).existsSync() &&
        Directory(_join(directory.path, 'lib')).existsSync();
  }).toList(growable: false)
    ..sort((left, right) => left.path.compareTo(right.path));

  var failed = false;
  for (final package in packages) {
    final outputPath = _join(outputRoot.absolute.path, _basename(package.path));
    stdout.writeln('> dart doc --output $outputPath (${package.path})');
    final result = await Process.run(
      'dart',
      <String>['doc', '--output', outputPath],
      workingDirectory: package.path,
      runInShell: Platform.isWindows,
    );
    final output = '${result.stdout}${result.stderr}';
    stdout.write(output);
    if (result.exitCode != 0 || _hasWarnings(output)) {
      failed = true;
    }
  }

  if (failed) {
    stderr.writeln('Dart documentation gate failed.');
    exitCode = 1;
  }
}

bool _hasWarnings(String output) {
  return output.contains(' warning:') ||
      RegExp(r'Found [1-9][0-9]* warnings').hasMatch(output);
}

String _join(String first, String second) {
  final separator = Platform.pathSeparator;
  return '$first$separator$second';
}

String _basename(String path) {
  final normalized = path.replaceAll('\\', '/');
  return normalized.substring(normalized.lastIndexOf('/') + 1);
}
