// 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:meta/meta.dart';
import 'package:path/path.dart' as path;

/// Makes sure that the path we were given contains some of the expected
/// libraries.
@visibleForTesting
const List<String> dartdocDirectiveCanaryLibraries = <String>[
  'animation',
  'cupertino',
  'material',
  'widgets',
  'rendering',
  'flutter_driver',
];

/// Makes sure that the path we were given contains some of the expected
/// HTML files.
@visibleForTesting
const List<String> dartdocDirectiveCanaryFiles = <String>[
  'Widget-class.html',
  'Material-class.html',
  'Canvas-class.html',
];

/// Scans the dartdoc HTML output in the provided `dartDocDir` 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(Directory dartDocDir) {
  if (!dartDocDir.existsSync()) {
    throw Exception('Directory with dartdoc output (${dartDocDir.path}) does not exist.');
  }

  // Make a copy since this will be mutated
  final List<String> canaryLibraries = dartdocDirectiveCanaryLibraries.toList();
  final List<String> canaryFiles = dartdocDirectiveCanaryFiles.toList();

  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(Directory(args.single));
}
