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

/// This file contains code to generate scanner and parser message
/// based on the information in pkg/front_end/messages.yaml.
///
/// For each message in messages.yaml that contains an 'index:' field,
/// this tool generates an error with the name specified by the 'analyzerCode:'
/// field and an entry in the fastaAnalyzerErrorList for that generated error.
/// The text in the 'analyzerCode:' field must contain the name of the class
/// containing the error and the name of the error separated by a `.`
/// (e.g. ParserErrorCode.EQUALITY_CANNOT_BE_EQUALITY_OPERAND).
///
/// It is expected that 'pkg/front_end/tool/fasta generate-messages'
/// has already been successfully run.
library;

import 'dart:convert';
import 'dart:io';

import 'package:_fe_analyzer_shared/src/scanner/scanner.dart';
import 'package:analyzer_testing/package_root.dart' as pkg_root;
import 'package:analyzer_utilities/tools.dart';
import 'package:collection/collection.dart';
import 'package:path/path.dart';

import 'error_code_info.dart';

Future<void> main() async {
  await GeneratedContent.generateAll(analyzerPkgPath, allTargets);

  _SyntacticErrorGenerator()
    ..checkForManualChanges()
    ..printSummary();
}

/// A list of all targets generated by this code generator.
final List<GeneratedContent> allTargets = _analyzerGeneratedFiles();

/// Generates a list of [GeneratedContent] objects describing all the analyzer
/// files that need to be generated.
List<GeneratedContent> _analyzerGeneratedFiles() {
  var classesByFile = <String, List<ErrorClassInfo>>{};
  for (var errorClassInfo in errorClasses) {
    (classesByFile[errorClassInfo.filePath] ??= []).add(errorClassInfo);
  }
  var generatedCodes = <String>[];
  return [
    for (var entry in classesByFile.entries)
      GeneratedFile(entry.key, (String pkgPath) async {
        var codeGenerator = _AnalyzerErrorGenerator(
          entry.value,
          generatedCodes,
        );
        codeGenerator.generate();
        return codeGenerator.out.toString();
      }),
    GeneratedFile('lib/src/error/error_code_values.g.dart', (
      String pkgPath,
    ) async {
      var codeGenerator = _ErrorCodeValuesGenerator(generatedCodes);
      codeGenerator.generate();
      return codeGenerator.out.toString();
    }),
  ];
}

/// Code generator for analyzer error classes.
class _AnalyzerErrorGenerator {
  final List<ErrorClassInfo> errorClasses;

  final List<String> generatedCodes;

  final StringBuffer out = StringBuffer('''
// 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.

// THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'pkg/analyzer/messages.yaml' and run
// 'dart run pkg/analyzer/tool/messages/generate.dart' to update.

// While transitioning `HintCodes` to `WarningCodes`, we refer to deprecated
// codes here.
// ignore_for_file: deprecated_member_use_from_same_package
// 
// Generated comments don't quite align with flutter style.
// ignore_for_file: flutter_style_todos

/// @docImport 'package:analyzer/src/dart/error/syntactic_errors.g.dart';
/// @docImport 'package:analyzer/src/error/inference_error.dart';
library;
''');

  _AnalyzerErrorGenerator(this.errorClasses, this.generatedCodes);

  void generate() {
    var imports = {'package:analyzer/error/error.dart'};
    bool shouldGenerateFastaAnalyzerErrorCodes = false;
    for (var errorClass in errorClasses) {
      imports.addAll(errorClass.extraImports);
      if (errorClass.includeCfeMessages) {
        shouldGenerateFastaAnalyzerErrorCodes = true;
      }
      analyzerMessages[errorClass.name]!.forEach((_, errorCodeInfo) {
        if (errorCodeInfo is AliasErrorCodeInfo) {
          imports.add(errorCodeInfo.aliasForFilePath.toPackageAnalyzerUri);
        }
      });
    }
    out.writeln();
    for (var importPath in imports.toList()..sort()) {
      out.writeln("import ${json.encode(importPath)};");
    }
    if (shouldGenerateFastaAnalyzerErrorCodes) {
      out.writeln();
      _generateFastaAnalyzerErrorCodeList();
    }
    for (var errorClass
        in errorClasses.toList()..sort((a, b) => a.name.compareTo(b.name))) {
      out.writeln();
      out.write('class ${errorClass.name} extends ${errorClass.superclass} {');
      var entries = [
        ...analyzerMessages[errorClass.name]!.entries,
        if (errorClass.includeCfeMessages)
          ...cfeToAnalyzerErrorCodeTables.analyzerCodeToInfo.entries,
      ].where((error) => !error.value.isRemoved).sortedBy((e) => e.key);
      for (var entry in entries) {
        var errorName = entry.key;
        var errorCodeInfo = entry.value;

        out.writeln();
        out.write(errorCodeInfo.toAnalyzerComments(indent: '  '));
        var deprecatedMessage = errorCodeInfo.deprecatedMessage;
        if (deprecatedMessage != null) {
          out.writeln('  @Deprecated("$deprecatedMessage")');
        }
        if (errorCodeInfo is AliasErrorCodeInfo) {
          out.writeln(
            '  static const ${errorCodeInfo.aliasForClass} $errorName =',
          );
          out.writeln('${errorCodeInfo.aliasFor};');
        } else {
          generatedCodes.add('${errorClass.name}.$errorName');
          out.writeln('  static const ${errorClass.name} $errorName =');
          out.writeln(errorCodeInfo.toAnalyzerCode(errorClass.name, errorName));
        }
      }
      out.writeln();
      out.writeln(
        '/// Initialize a newly created error code to have the given '
        '[name].',
      );
      out.writeln(
        'const ${errorClass.name}(String name, String problemMessage, {',
      );
      out.writeln('super.correctionMessage,');
      out.writeln('super.hasPublishedDocs = false,');
      out.writeln('super.isUnresolvedIdentifier = false,');
      out.writeln('String? uniqueName,');
      out.writeln('}) : super(');
      out.writeln('name: name,');
      out.writeln('problemMessage: problemMessage,');
      out.writeln("uniqueName: '${errorClass.name}.\${uniqueName ?? name}',");
      out.writeln(');');
      out.writeln();
      out.writeln('@override');
      out.writeln(
        'DiagnosticSeverity get severity => '
        '${errorClass.severityCode};',
      );
      out.writeln();
      out.writeln('@override');
      out.writeln('DiagnosticType get type => ${errorClass.typeCode};');
      out.writeln('}');
    }
  }

  void _generateFastaAnalyzerErrorCodeList() {
    out.writeln('final fastaAnalyzerErrorCodes = <DiagnosticCode?>[');
    for (var entry in cfeToAnalyzerErrorCodeTables.indexToInfo) {
      var name = cfeToAnalyzerErrorCodeTables.infoToAnalyzerCode[entry];
      out.writeln('${name == null ? 'null' : 'ParserErrorCode.$name'},');
    }
    out.writeln('];');
  }
}

class _ErrorCodeValuesGenerator {
  final List<String> generatedCodes;

  final StringBuffer out = StringBuffer('''
// Copyright (c) 2014, 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.

// THIS FILE IS GENERATED. DO NOT EDIT.
//
// Instead modify 'pkg/analyzer/messages.yaml' and run
// 'dart run pkg/analyzer/tool/messages/generate.dart' to update.

// We allow some snake_case and SCREAMING_SNAKE_CASE identifiers in generated
// code, as they match names declared in the source configuration files.
// ignore_for_file: constant_identifier_names

// While transitioning `HintCodes` to `WarningCodes`, we refer to deprecated
// codes here.
// ignore_for_file: deprecated_member_use_from_same_package
''');

  _ErrorCodeValuesGenerator(this.generatedCodes);

  void generate() {
    // The scanner error codes are not yet being generated, so we need to add
    // them to the list explicitly.
    generatedCodes.addAll([
      'ScannerErrorCode.EXPECTED_TOKEN',
      'ScannerErrorCode.ILLEGAL_CHARACTER',
      'ScannerErrorCode.MISSING_DIGIT',
      'ScannerErrorCode.MISSING_HEX_DIGIT',
      'ScannerErrorCode.MISSING_IDENTIFIER',
      'ScannerErrorCode.MISSING_QUOTE',
      'ScannerErrorCode.UNABLE_GET_CONTENT',
      'ScannerErrorCode.UNEXPECTED_DOLLAR_IN_STRING',
      'ScannerErrorCode.UNSUPPORTED_OPERATOR',
      'ScannerErrorCode.UNTERMINATED_MULTI_LINE_COMMENT',
      'ScannerErrorCode.UNTERMINATED_STRING_LITERAL',
      'TodoCode.TODO',
      'TodoCode.FIXME',
      'TodoCode.HACK',
      'TodoCode.UNDONE',
    ]);
    generatedCodes.sort();

    out.writeln();
    out.writeln(r'''
import 'package:_fe_analyzer_shared/src/base/analyzer_public_api.dart';
import 'package:_fe_analyzer_shared/src/base/errors.dart';
import 'package:analyzer/src/dart/error/ffi_code.dart';
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/manifest/manifest_warning_code.dart';
import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
''');
    out.writeln();
    out.writeln(
      "@AnalyzerPublicApi(message: 'exported by lib/error/error.dart')",
    );
    out.writeln('const List<DiagnosticCode> errorCodeValues = [');
    for (var name in generatedCodes) {
      out.writeln('  $name,');
    }
    out.writeln('];');
  }
}

class _SyntacticErrorGenerator {
  final String errorConverterSource;
  final String parserSource;

  factory _SyntacticErrorGenerator() {
    String frontEndSharedPkgPath = normalize(
      join(pkg_root.packageRoot, '_fe_analyzer_shared'),
    );

    String errorConverterSource =
        File(
          join(
            analyzerPkgPath,
            joinAll(posix.split('lib/src/fasta/error_converter.dart')),
          ),
        ).readAsStringSync();
    String parserSource =
        File(
          join(
            frontEndSharedPkgPath,
            joinAll(posix.split('lib/src/parser/parser.dart')),
          ),
        ).readAsStringSync();

    return _SyntacticErrorGenerator._(errorConverterSource, parserSource);
  }

  _SyntacticErrorGenerator._(this.errorConverterSource, this.parserSource);

  void checkForManualChanges() {
    // Check for ParserErrorCodes that could be removed from
    // error_converter.dart now that those ParserErrorCodes are auto generated.
    int converterCount = 0;
    for (var errorCode
        in cfeToAnalyzerErrorCodeTables.infoToAnalyzerCode.values) {
      if (errorConverterSource.contains('"$errorCode"')) {
        if (converterCount == 0) {
          print('');
          print(
            'The following ParserErrorCodes could be removed'
            ' from error_converter.dart:',
          );
        }
        print('  $errorCode');
        ++converterCount;
      }
    }
    if (converterCount > 3) {
      print('  $converterCount total');
    }

    // Fail if there are manual changes to be made, but do so
    // in a fire and forget manner so that the files are still generated.
    if (converterCount > 0) {
      print('');
      throw 'Error: missing manual code changes';
    }
  }

  void printSummary() {
    // Build a map of error message to ParserErrorCode
    var messageToName = <String, String>{};
    for (var entry in analyzerMessages['ParserErrorCode']!.entries) {
      String message = entry.value.problemMessage.replaceAll(
        RegExp(r'\{\d+\}'),
        '',
      );
      messageToName[message] = entry.key;
    }

    String messageFromEntryTemplate(ErrorCodeInfo entry) {
      String problemMessage = entry.problemMessage;
      String message = problemMessage.replaceAll(RegExp(r'#\w+'), '');
      return message;
    }

    // Remove entries that have already been translated
    for (ErrorCodeInfo entry
        in cfeToAnalyzerErrorCodeTables.infoToAnalyzerCode.keys) {
      messageToName.remove(messageFromEntryTemplate(entry));
    }

    // Print the # of autogenerated ParserErrorCodes.
    print(
      '${messageToName.length} of '
      '${cfeToAnalyzerErrorCodeTables.infoToAnalyzerCode.length} ParserErrorCodes generated.',
    );

    // List the ParserErrorCodes that could easily be auto generated
    // but have not been already.
    var analyzerToFasta = <String, List<String>>{};
    frontEndMessages.forEach((fastaName, entry) {
      var analyzerName = messageToName[messageFromEntryTemplate(entry)];
      if (analyzerName != null) {
        analyzerToFasta
            .putIfAbsent(analyzerName, () => <String>[])
            .add(fastaName);
      }
    });
    if (analyzerToFasta.isNotEmpty) {
      print('');
      print('The following ParserErrorCodes could be auto generated:');
      for (String analyzerName in analyzerToFasta.keys.toList()..sort()) {
        List<String> fastaNames = analyzerToFasta[analyzerName]!;
        if (fastaNames.length == 1) {
          print('  $analyzerName = ${fastaNames.first}');
        } else {
          print('  $analyzerName = $fastaNames');
        }
      }
      if (analyzerToFasta.length > 3) {
        print('  ${analyzerToFasta.length} total');
      }
    }

    // List error codes in the parser that have not been translated.
    var untranslatedFastaErrorCodes = <String>{};
    Token token = scanString(parserSource).tokens;
    while (!token.isEof) {
      if (token.isIdentifier) {
        String? fastaErrorCode;
        String lexeme = token.lexeme;
        if (lexeme.length > 7) {
          if (lexeme.startsWith('message')) {
            fastaErrorCode = lexeme.substring(7);
          } else if (lexeme.length > 8) {
            if (lexeme.startsWith('template')) {
              fastaErrorCode = lexeme.substring(8);
            }
          }
        }
        if (fastaErrorCode != null &&
            cfeToAnalyzerErrorCodeTables.frontEndCodeToInfo[fastaErrorCode] ==
                null) {
          untranslatedFastaErrorCodes.add(fastaErrorCode);
        }
      }
      token = token.next!;
    }
    if (untranslatedFastaErrorCodes.isNotEmpty) {
      print('');
      print('The following error codes in the parser are not auto generated:');
      var sorted = untranslatedFastaErrorCodes.toList()..sort();
      for (String fastaErrorCode in sorted) {
        String analyzerCode = '';
        String problemMessage = '';
        var entry = frontEndMessages[fastaErrorCode];
        if (entry != null) {
          // TODO(paulberry): handle multiple analyzer codes
          if (entry.index == null && entry.analyzerCode.length == 1) {
            analyzerCode = entry.analyzerCode.single;
            problemMessage = entry.problemMessage;
          }
        }
        print(
          '  ${fastaErrorCode.padRight(30)} --> $analyzerCode'
          '\n      $problemMessage',
        );
      }
    }
  }
}

extension on String {
  String get toPackageAnalyzerUri =>
      replaceFirst(RegExp('^lib/'), 'package:analyzer/');
}
