// 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 'dart pkg/front_end/tool/generate_messages.dart'
/// has already been successfully run.
library;

import 'dart:convert';

import 'package:analyzer_testing/package_root.dart' as pkg_root;
import 'package:analyzer_utilities/analyzer_messages.dart';
import 'package:analyzer_utilities/messages.dart';
import 'package:analyzer_utilities/tools.dart';

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

/// 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 = <GeneratedDiagnosticFile, List<DiagnosticClassInfo>>{};
  for (var diagnosticClassInfo in diagnosticClasses) {
    // Lint codes are generated separately.
    if (diagnosticClassInfo == linterLintCodeInfo) continue;

    (classesByFile[diagnosticClassInfo.file] ??= []).add(diagnosticClassInfo);
  }
  return [
    for (var entry in classesByFile.entries)
      GeneratedFile(entry.key.path, (pkgRoot) async {
        var codeGenerator = _AnalyzerDiagnosticGenerator(
          entry.key,
          entry.value,
        );
        codeGenerator.generate();
        return codeGenerator.out.toString();
      }),
    GeneratedFile('analyzer/lib/src/diagnostic/diagnostic_code_values.g.dart', (
      pkgRoot,
    ) async {
      var codeGenerator = _DiagnosticCodeValuesGenerator();
      codeGenerator.generate();
      return codeGenerator.out.toString();
    }),
  ];
}

/// Code generator for analyzer diagnostic classes.
class _AnalyzerDiagnosticGenerator {
  final GeneratedDiagnosticFile file;

  final List<DiagnosticClassInfo> diagnosticClasses;

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

  _AnalyzerDiagnosticGenerator(this.file, this.diagnosticClasses);

  void generate() {
    file.package.writeIgnoresTo(out);
    out.writeln();
    out.write('''
part of ${json.encode(file.parentLibrary)};
''');
    for (var diagnosticClass
        in diagnosticClasses.toList()
          ..sort((a, b) => a.name.compareTo(b.name))) {
      out.writeln();
      if (diagnosticClass.comment.isNotEmpty) {
        diagnosticClass.comment.trimRight().split('\n').forEach((line) {
          out.writeln('/// $line');
        });
      }
      out.write(
        'class ${diagnosticClass.name} extends DiagnosticCodeWithExpectedTypes {',
      );
      var memberAccumulator = MemberAccumulator();

      for (var message
          in diagnosticTables.activeMessagesByPackage[diagnosticClass
              .file
              .package]!) {
        if (message.analyzerCode.diagnosticClass != diagnosticClass) continue;

        LocatedError.wrap(span: message.keySpan, () {
          message.toAnalyzerCode(memberAccumulator: memberAccumulator);
        });
      }

      var constructor = StringBuffer();
      constructor.writeln(
        '/// Initialize a newly created error code to have the given '
        '[name].',
      );
      constructor.writeln('const ${diagnosticClass.name}({');
      constructor.writeln('required super.name,');
      constructor.writeln('required super.problemMessage,');
      constructor.writeln('super.correctionMessage,');
      constructor.writeln('super.hasPublishedDocs = false,');
      constructor.writeln('super.isUnresolvedIdentifier = false,');
      constructor.writeln('required super.uniqueName,');
      constructor.writeln('required super.expectedTypes,');
      constructor.writeln('}) : super(');
      constructor.writeln('type: ${diagnosticClass.typeCode},');
      constructor.writeln(');');
      memberAccumulator.constructors[''] = constructor.toString();

      memberAccumulator.writeTo(out);
      out.writeln('}');
    }
  }
}

class _DiagnosticCodeValuesGenerator {
  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.
''');

  void generate() {
    AnalyzerDiagnosticPackage.analyzer.writeIgnoresTo(out);
    out.writeln();
    out.writeln(r'''
part of 'diagnostic_code_values.dart';
''');
    out.writeln();
    out.writeln(
      "@AnalyzerPublicApi(message: 'exported by lib/error/error.dart')",
    );
    out.writeln('const List<DiagnosticCode> diagnosticCodeValues = [');
    for (var message
        in diagnosticTables.activeMessagesByPackage[AnalyzerDiagnosticPackage
            .analyzer]!) {
      out.writeln('  ${message.analyzerCode.analyzerCodeReference},');
    }
    out.writeln('];');
    out.writeln();
    _generateSharedAnalyzerCodeList();
    out.writeln(
      "@AnalyzerPublicApi(message: 'exported by lib/error/error.dart')",
    );
    out.writeln('@Deprecated("Use \'diagnosticCodeValues\' instead")');
    out.writeln(
      'List<DiagnosticCode> get errorCodeValues => diagnosticCodeValues;',
    );
  }

  void _generateSharedAnalyzerCodeList() {
    out.writeln('final sharedAnalyzerCodes = <DiagnosticCode>[');
    for (var entry in diagnosticTables.sortedSharedDiagnostics) {
      out.writeln('${entry.analyzerCode.analyzerCodeReference},');
    }
    out.writeln('];');
  }
}
