// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// @dart = 2.8

import 'dart:io';

import 'package:path/path.dart' as path;

/// Scans the dartdoc HTML output in the provided `htmlOutputPath` for
/// unresolved dartdoc directives (`{@foo x y}`).
///
/// Dartdoc usually replaces those directives with other content. However,
/// if the directive is misspelled (or contains other errors) it is placed
/// verbatim into the HTML output. That's not desirable and this check verifies
/// that no directives appear verbatim in the output by checking that the
/// string `{@` does not appear in the HTML output outside of <code> sections.
///
/// The string `{@` is allowed in <code> sections, because those may contain
/// sample code where the sequence is perfectly legal, e.g. for required named
/// parameters of a method:
///
/// ```
/// void foo({@required int bar});
/// ```
void checkForUnresolvedDirectives(String htmlOutputPath) {
  final Directory dartDocDir = Directory(htmlOutputPath);
  if (!dartDocDir.existsSync()) {
    throw Exception('Directory with dartdoc output (${dartDocDir.path}) does not exist.');
  }

  // Makes sure that the path we were given contains some of the expected
  // libraries and HTML files.
  final List<String> canaryLibraries = <String>[
    'animation',
    'cupertino',
    'material',
    'widgets',
    'rendering',
    'flutter_driver',
  ];
  final List<String> canaryFiles = <String>[
    'Widget-class.html',
    'Material-class.html',
    'Canvas-class.html',
  ];

  print('Scanning for unresolved dartdoc directives...');

  final List<FileSystemEntity> toScan = dartDocDir.listSync();
  int count = 0;

  while (toScan.isNotEmpty) {
    final FileSystemEntity entity = toScan.removeLast();
    if (entity is File) {
      if (path.extension(entity.path) != '.html') {
        continue;
      }
      canaryFiles.remove(path.basename(entity.path));
      count += _scanFile(entity);
    } else if (entity is Directory) {
      canaryLibraries.remove(path.basename(entity.path));
      toScan.addAll(entity.listSync());
    } else {
      throw Exception('$entity is neither file nor directory.');
    }
  }

  if (canaryLibraries.isNotEmpty) {
    throw Exception('Did not find docs for the following libraries: ${canaryLibraries.join(', ')}.');
  }
  if (canaryFiles.isNotEmpty) {
    throw Exception('Did not find docs for the following files: ${canaryFiles.join(', ')}.');
  }
  if (count > 0) {
    throw Exception('Found $count unresolved dartdoc directives (see log above).');
  }
  print('No unresolved dartdoc directives detected.');
}

int _scanFile(File file) {
  assert(path.extension(file.path) == '.html');
  final Iterable<String> matches = _pattern.allMatches(file.readAsStringSync())
      .map((RegExpMatch m ) => m.group(0));

  if (matches.isNotEmpty) {
    stderr.writeln('Found unresolved dartdoc directives in ${file.path}:');
    for (final String match in matches) {
      stderr.writeln('  $match');
    }
  }
  return matches.length;
}

// Matches all `{@` that are not within `<code></code>` sections.
//
// This regex may lead to false positives if the docs ever contain nested tags
// inside <code> sections. Since we currently don't do that, doing the matching
// with a regex is a lot faster than using an HTML parser to strip out the
// <code> sections.
final RegExp _pattern = RegExp(r'({@[^}\n]*}?)(?![^<>]*</code)');

// Usually, the checker is invoked directly from `dartdoc.dart`. Main method
// is included for convenient local runs without having to regenerate
// the dartdocs every time.
//
// Provide the path to the dartdoc HTML output as an argument when running the
// program.
void main(List<String> args) {
  if (args.length != 1) {
    throw Exception('Must provide the path to the dartdoc HTML output as argument.');
  }
  if (!Directory(args.single).existsSync()) {
    throw Exception('The dartdoc HTML output directory ${args.single} does not exist.');
  }
  checkForUnresolvedDirectives(args.single);
}
