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

// Read the ../README.md file for the recognized syntax.

import 'dart:collection';
import 'dart:io';

import 'package:analyzer/dart/analysis/analysis_context_collection.dart';
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/analysis/results.dart';
import 'package:analyzer/dart/analysis/utilities.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/diagnostic/diagnostic.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/overlay_file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/source/line_info.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/util/comment.dart';
import 'package:path/path.dart' as path;

final libDir = Directory(path.join('sdk', 'lib'));
void main(List<String> args) async {
  if (!libDir.existsSync()) {
    print('Please run this tool from the root of the sdk repository.');
    exit(1);
  }

  print('Validating the dartdoc code samples from the dart: libraries.');
  print('');
  print('To run this tool, run `dart tools/verify_docs/bin/verify_docs.dart`.');
  print('');
  print('For documentation about how to author dart: code samples,'
      ' see tools/verify_docs/README.md.');
  print('');

  final coreLibraries = args.isEmpty
      ? libDir.listSync().whereType<Directory>().toList()
      : args.map(parseArg).toList();
  coreLibraries.sort((a, b) => a.path.compareTo(b.path));

  // Skip some dart: libraries.
  const skipLibraries = {
    'html',
    'indexed_db',
    'svg',
    'vmservice',
    'web_audio',
    'web_gl',
    'web_sql'
  };
  coreLibraries.removeWhere(
    (lib) => skipLibraries.contains(path.basename(lib.path)),
  );

  var hadErrors = false;
  for (final dir in coreLibraries) {
    hadErrors |= !(await validateLibrary(dir));
  }

  exitCode = hadErrors ? 1 : 0;
}

Future<bool> validateLibrary(Directory dir) async {
  final libName = path.basename(dir.path);

  final analysisHelper = AnalysisHelper(libName);

  print('## dart:$libName');
  print('');

  var validDocs = true;

  for (final file in dir
      .listSync(recursive: true)
      .whereType<File>()
      .where((file) => file.path.endsWith('.dart'))) {
    validDocs &= await verifyFile(analysisHelper, libName, file, dir);
  }

  return validDocs;
}

Future<bool> verifyFile(
  AnalysisHelper analysisHelper,
  String coreLibName,
  File file,
  Directory parent,
) async {
  final text = file.readAsStringSync();
  var parseResult = parseString(
    content: text,
    featureSet: FeatureSet.latestLanguageVersion(),
    path: file.path,
    throwIfDiagnostics: false,
  );

  // Throw if there are syntactic errors.
  var syntacticErrors = parseResult.errors.where((error) {
    return error.errorCode.type == ErrorType.SYNTACTIC_ERROR;
  }).toList();
  if (syntacticErrors.isNotEmpty) {
    throw Exception(syntacticErrors);
  }

  final sampleAssumptions = findFileAssumptions(text);

  var visitor = ValidateCommentCodeSamplesVisitor(
    analysisHelper,
    coreLibName,
    file.path,
    parseResult.lineInfo,
    sampleAssumptions,
  );
  await visitor.process(parseResult);
  return !visitor.hadErrors;
}

/// Visit a compilation unit and validate the code samples found in dartdoc
/// comments.
class ValidateCommentCodeSamplesVisitor extends GeneralizingAstVisitor {
  final AnalysisHelper analysisHelper;
  final String coreLibName;
  final String filePath;
  final LineInfo lineInfo;
  final String? sampleAssumptions;

  final List<CodeSample> samples = [];
  bool hadErrors = false;

  ValidateCommentCodeSamplesVisitor(
    this.analysisHelper,
    this.coreLibName,
    this.filePath,
    this.lineInfo,
    this.sampleAssumptions,
  );

  Future process(ParseStringResult parseResult) async {
    // collect code samples
    visitCompilationUnit(parseResult.unit);

    // analyze them
    for (CodeSample sample in samples) {
      await validateCodeSample(sample);
    }
  }

  @override
  void visitAnnotatedNode(AnnotatedNode node) {
    _handleDocumentableNode(node);
    super.visitAnnotatedNode(node);
  }

  void _handleDocumentableNode(AnnotatedNode node) {
    final docComment = node.documentationComment;
    if (docComment == null || !docComment.isDocumentation) {
      return;
    }

    const sampleStart = '```dart';
    const sampleEnd = '```';

    final text = getCommentNodeRawText(docComment)!;
    final commentOffset = docComment.offset;
    final commentLineStart = lineInfo.getLocation(commentOffset).lineNumber;
    if (!text.contains(sampleStart)) {
      return;
    }

    var offset = text.indexOf(sampleStart);
    while (offset != -1) {
      // Collect template directives, like "```dart import:async".
      final codeFenceSuffix = text
          .substring(offset + sampleStart.length, text.indexOf('\n', offset))
          .trim();

      offset = text.indexOf('\n', offset) + 1;
      final end = text.indexOf(sampleEnd, offset);

      var snippet = text.substring(offset, end);
      snippet = snippet.substring(0, snippet.lastIndexOf('\n'));

      List<String> lines = snippet.split('\n');
      var startLineNumber = commentLineStart +
          text.substring(0, offset - 1).split('\n').length -
          1;
      if (codeFenceSuffix == "continued") {
        if (samples.isEmpty) {
          throw "Continued code block without previous code";
        }
        samples.last = samples.last.append(lines, startLineNumber);
      } else {
        final directives = Set.unmodifiable(codeFenceSuffix.split(' '));
        samples.add(
          CodeSample(
            [for (var e in lines) '  ${cleanDocLine(e)}'],
            coreLibName: coreLibName,
            directives: directives,
            lineStartOffset: startLineNumber,
          ),
        );
      }

      offset = text.indexOf(sampleStart, offset);
    }
  }

  // RegExp detecting various top-level declarations or `main(`.
  //
  // If the top-level declaration is `library` or `import`,
  // then match 1 (`libdecl`) will be non-null.
  // This is a sign that no auto-imports should be added.
  //
  // If an import declaration is included in the sample, no
  // assumed-declarations are added.
  // Use the `import:foo` template to import other `dart:` libraries
  // instead of writing them explicitly to.
  //
  // Captures:
  // 1/libdecl: Non-null if mathcing a `library` declaration.
  // 2: Internal use, quote around import URI.
  // 3/importuri: Import URI.
  final _toplevelDeclarationRE = RegExp(r'^\s*(?:'
      r'library\b(?<libdecl>)|'
      r'''import (['"])(?<importuri>.*?)\2|'''
      r'class\b|mixin\b|enum\b|extension\b|typedef\b|.*\bmain\('
      r')');

  validateCodeSample(CodeSample sample) async {
    final lines = sample.lines;

    // The default imports includes the library itself
    // and any import directives.
    Set<String> autoImports = sample.imports;

    // One of 'none', 'top, 'main', or 'expression'.
    String template;

    bool hasImport = false;

    final templateDirective = sample.templateDirective;
    if (templateDirective != null) {
      template = templateDirective;
    } else {
      // Scan lines for top-level declarations.
      bool hasTopDeclaration = false;
      bool hasLibraryDeclaration = false;
      for (var line in lines) {
        var topDeclaration = _toplevelDeclarationRE.firstMatch(line);
        if (topDeclaration != null) {
          hasTopDeclaration = true;
          hasLibraryDeclaration |=
              (topDeclaration.namedGroup("libdecl") != null);
          var importDecl = topDeclaration.namedGroup("importuri");
          if (importDecl != null) {
            hasImport = true;
            if (importDecl.startsWith('dart:')) {
              // Remove explicit imports from automatic imports
              // to avoid duplicate import warnings.
              autoImports.remove(importDecl.substring('dart:'.length));
            }
          }
        }
      }
      if (hasLibraryDeclaration) {
        template = 'none';
      } else if (hasTopDeclaration) {
        template = 'top';
      } else if (lines.length == 1 && !lines.first.contains(';')) {
        // If single line with no `;`, assume expression.
        template = 'expression';
      } else {
        // Otherwise default to `main`.
        template = 'main';
      }
    }

    var buffer = StringBuffer();

    if (template != 'none') {
      for (var library in autoImports) {
        buffer.writeln("import 'dart:$library';");
      }
      if (!hasImport) {
        buffer.write(sampleAssumptions ?? '');
      }
    }
    if (template == 'none' || template == 'top') {
      buffer.writeAllLines(lines);
    } else if (template == 'main') {
      buffer
        ..writeln('void main() async {')
        ..writeAllLines(lines)
        ..writeln('}');
    } else if (template == 'expression') {
      assert(lines.length >= 1);
      buffer
        ..writeln('void main() async =>')
        ..writeAllLines(lines.take(lines.length - 1))
        ..writeln("${lines.last.trimRight()};");
    } else {
      throw 'unexpected template directive: $template';
    }

    final text = buffer.toString();

    final result = await analysisHelper.resolveFile(text);

    if (result is ResolvedUnitResult) {
      var errors = SplayTreeSet<AnalysisError>.from(
        result.errors,
        (a, b) {
          var value = a.offset.compareTo(b.offset);
          if (value == 0) {
            value = a.message.compareTo(b.message);
          }
          return value;
        },
      );

      // Filter out unused imports, since we speculatively add imports to some
      // samples.
      errors.removeWhere(
        (e) => e.errorCode == HintCode.UNUSED_IMPORT,
      );

      // Also, don't worry about 'unused_local_variable' and related; this may
      // be intentional in samples.
      errors.removeWhere(
        (e) =>
            e.errorCode == HintCode.UNUSED_LOCAL_VARIABLE ||
            e.errorCode == HintCode.UNUSED_ELEMENT,
      );

      // Remove warnings about deprecated member use from the same library.
      errors.removeWhere(
        (e) =>
            e.errorCode == HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE ||
            e.errorCode ==
                HintCode.DEPRECATED_MEMBER_USE_FROM_SAME_PACKAGE_WITH_MESSAGE,
      );

      // Handle edge case around dart:_http
      errors.removeWhere((e) {
        if (e.message.contains("'dart:_http'")) {
          return e.errorCode == HintCode.UNNECESSARY_IMPORT ||
              e.errorCode == CompileTimeErrorCode.IMPORT_INTERNAL_LIBRARY;
        }
        return false;
      });

      if (errors.isNotEmpty) {
        print('$filePath:${sample.lineStartOffset}: ${errors.length} errors');

        hadErrors = true;

        for (final error in errors) {
          final location = result.lineInfo.getLocation(error.offset);
          print(
            '  ${_severity(error.severity)}: ${error.message} '
            '[$location] (${error.errorCode.name.toLowerCase()})',
          );
        }
        print('');

        // Print out the code sample.
        print(sample.lines
            .map((line) =>
                '  >${line.length >= 5 ? line.substring(5) : line.trimLeft()}')
            .join('\n'));
        print('');
      }
    } else {
      throw 'unexpected result type: ${result}';
    }

    return;
  }
}

String cleanDocLine(String line) {
  var copy = line.trimLeft();
  if (copy.startsWith('///')) {
    copy = copy.substring(3);
  } else if (copy.startsWith('*')) {
    copy = copy.substring(1);
  }
  return copy.padLeft(line.length, ' ');
}

class CodeSample {
  /// Currently valid template names.
  static const validTemplates = ['none', 'top', 'main', 'expression'];

  final String coreLibName;
  final Set<String> directives;
  final List<String> lines;
  final int lineStartOffset;

  CodeSample(
    this.lines, {
    required this.coreLibName,
    this.directives = const {},
    required this.lineStartOffset,
  });

  String get text => lines.join('\n');

  bool get hasTemplateDirective => templateDirective != null;

  /// The specified template, or `null` if no template is specified.
  ///
  /// A specified template must be of [validTemplates].
  String? get templateDirective {
    const prefix = 'template:';

    for (var directive in directives) {
      if (directive.startsWith(prefix)) {
        var result = directive.substring(prefix.length);
        if (!validTemplates.contains(result)) {
          throw "Invalid template name: $result";
        }
        return result;
      }
    }
    return null;
  }

  /// The implicit or explicitly requested imports.
  Set<String> get imports => {
        if (coreLibName != 'internal' && coreLibName != 'core') coreLibName,
        for (var directive in directives)
          if (directive.startsWith('import:'))
            directive.substring('import:'.length)
      };

  /// Creates a new code sample by appending [lines] to this sample.
  ///
  /// The new sample only differs from this sample in that it has
  /// more lines appended, first `this.lines`, then a gap of `  //` lines
  /// and then [lines].
  CodeSample append(List<String> lines, int lineStartOffset) {
    var gapSize = lineStartOffset - (this.lineStartOffset + this.lines.length);
    return CodeSample(
        [...this.lines, for (var i = 0; i < gapSize; i++) "  //", ...lines],
        coreLibName: coreLibName,
        directives: directives,
        lineStartOffset: this.lineStartOffset);
  }
}

/// Find and return any '// Examples can assume:' sample text.
String? findFileAssumptions(String text) {
  var inAssumptions = false;
  var assumptions = <String>[];

  for (final line in text.split('\n')) {
    if (line == '// Examples can assume:') {
      inAssumptions = true;
    } else if (line.trim().isEmpty && inAssumptions) {
      inAssumptions = false;
    } else if (inAssumptions) {
      assumptions.add(line.substring('// '.length));
    }
  }

  return '${assumptions.join('\n')}\n';
}

String _severity(Severity severity) {
  switch (severity) {
    case Severity.info:
      return 'info';
    case Severity.warning:
      return 'warning';
    case Severity.error:
      return 'error';
  }
}

class AnalysisHelper {
  final String libraryName;
  final resourceProvider =
      OverlayResourceProvider(PhysicalResourceProvider.INSTANCE);
  final pathRoot = Platform.isWindows ? r'c:\' : '/';
  late AnalysisContextCollection collection;
  int index = 0;

  AnalysisHelper(this.libraryName) {
    resourceProvider.pathContext;

    collection = AnalysisContextCollection(
      includedPaths: ['$pathRoot$libraryName'],
      resourceProvider: resourceProvider,
    );
  }

  Future<SomeResolvedUnitResult> resolveFile(String contents) async {
    final samplePath =
        '$pathRoot$libraryName${resourceProvider.pathContext.separator}'
        'sample_${index++}.dart';
    resourceProvider.setOverlay(
      samplePath,
      content: contents,
      modificationStamp: 0,
    );

    var analysisContext = collection.contextFor(samplePath);
    var analysisSession = analysisContext.currentSession;
    return await analysisSession.getResolvedUnit(samplePath);
  }
}

// Helper function to make things easier to read.
extension on StringBuffer {
  /// Write every line, right-trimmed, of [lines] with a newline after.
  void writeAllLines(Iterable<String> lines) {
    for (var line in lines) {
      this.writeln(line.trimRight());
    }
  }
}

/// Interprets [arg] as directory containing a platform library.
///
/// If [arg] is `dart:foo`, the directory is the default directory for
/// the `dart:foo` library source.
/// Otherwise, if [arg] is a directory (relative to the current directory)
/// which exists, that is the result.
/// Otherwise, if [arg] is the name of a platform library,
/// like `foo` where `dart:foo` is a platform library,
/// the result is the default directory for that library's source.
/// Otherwise it's treated as a directory relative to the current directory,
/// which doesn't exist (but that's what the error will refer to).
Directory parseArg(String arg) {
  if (arg.startsWith('dart:')) {
    return Directory(path.join(libDir.path, arg.substring('dart:'.length)));
  }
  var dir = Directory(arg);
  if (dir.existsSync()) return dir;
  var relDir = Directory(path.join(libDir.path, arg));
  if (relDir.existsSync()) return relDir;
  return dir;
}
