// 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.

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));

      // TODO(goderbauer): Remove this exception when https://github.com/dart-lang/dartdoc/issues/2272 is fixed.
      if (entity.path.endsWith('-class.html') || entity.path.endsWith('-library.html') ) {
        continue;
      }

      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);
}
