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

import 'dart:convert' as json;
import 'dart:io';

import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart';
import 'package:kernel/ast.dart';

import '../base/command_line_reporting.dart';
import '../codes/cfe_codes.dart';
import 'analysis_helper.dart';

/// [AnalysisVisitor] that supports tracking error/problem occurrences in an
/// allowed list file.
class VerifyingAnalysis extends AnalysisVisitor {
  final String? _allowedListPath;

  Map _expectedJson = {};

  VerifyingAnalysis(DiagnosticMessageHandler onDiagnostic, Component component,
      this._allowedListPath, UriFilter? analyzedUrisFilter)
      : super(onDiagnostic, component, analyzedUrisFilter);

  void run({bool verbose = false, bool generate = false}) {
    if (!generate && _allowedListPath != null) {
      File file = new File(_allowedListPath);
      if (file.existsSync()) {
        try {
          _expectedJson = json.jsonDecode(file.readAsStringSync());
        } catch (e) {
          throw 'Error reading allowed list from $_allowedListPath: $e';
        }
      }
    }
    component.accept(this);
    if (generate && _allowedListPath != null) {
      Map<String, Map<String, int>> actualJson = {};
      forEachMessage(
          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
        Map<String, int> map = {};
        actualMessagesMap
            .forEach((String message, List<FormattedMessage> actualMessages) {
          map[message] = actualMessages.length;
        });
        actualJson[uri] = map;
      });

      new File(_allowedListPath).writeAsStringSync(
          new json.JsonEncoder.withIndent('  ').convert(actualJson));
      return;
    }

    int errorCount = 0;
    _expectedJson.forEach((uri, expectedMessages) {
      Map<String, List<FormattedMessage>>? actualMessagesMap =
          getMessagesForUri(uri);
      if (actualMessagesMap == null) {
        print("Error: Allowed-listing of uri '$uri' isn't used. "
            "Remove it from the allowed-list.");
        errorCount++;
      } else {
        expectedMessages.forEach((expectedMessage, expectedCount) {
          List<FormattedMessage>? actualMessages =
              actualMessagesMap[expectedMessage];
          if (actualMessages == null) {
            print("Error: Allowed-listing of message '$expectedMessage' "
                "in uri '$uri' isn't used. Remove it from the allowed-list.");
            errorCount++;
          } else {
            int actualCount = actualMessages.length;
            if (actualCount != expectedCount) {
              print("Error: Unexpected count of allowed message "
                  "'$expectedMessage' in uri '$uri'. "
                  "Expected $expectedCount, actual $actualCount:");
              print(
                  '----------------------------------------------------------');
              for (FormattedMessage message in actualMessages) {
                onDiagnostic(message);
              }
              print(
                  '----------------------------------------------------------');
              errorCount++;
            }
          }
        });
        actualMessagesMap
            .forEach((String message, List<FormattedMessage> actualMessages) {
          if (!expectedMessages.containsKey(message)) {
            for (FormattedMessage message in actualMessages) {
              onDiagnostic(message);
              errorCount++;
            }
          }
        });
      }
    });
    forEachMessage(
        (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
      if (!_expectedJson.containsKey(uri)) {
        actualMessagesMap
            .forEach((String message, List<FormattedMessage> actualMessages) {
          for (FormattedMessage message in actualMessages) {
            onDiagnostic(message);
            errorCount++;
          }
        });
      }
    });
    if (errorCount != 0) {
      print('$errorCount error(s) found.');
      print("""

********************************************************************************
*  Unexpected code patterns found by test:
*
*    ${relativizeUri(Platform.script)}
*
*  Please address the reported errors, or, if the errors are as expected, run
*
*    dart ${relativizeUri(Platform.script)} -g
*
*  to update the expectation file.
********************************************************************************
""");
      exit(-1);
    }
    if (verbose) {
      forEachMessage(
          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
        actualMessagesMap
            .forEach((String message, List<FormattedMessage> actualMessages) {
          for (FormattedMessage message in actualMessages) {
            // TODO(johnniwinther): It is unnecessarily complicated to just
            // add ' (allowed)' to an existing message!
            LocatedMessage locatedMessage = message.locatedMessage;
            String newMessageText =
                '${locatedMessage.messageObject.problemMessage} (allowed)';
            message = locatedMessage.withFormatting(
                formatWithLocationNoSdk(
                    new LocatedMessage(
                        locatedMessage.uri,
                        locatedMessage.charOffset,
                        locatedMessage.length,
                        new Message(locatedMessage.messageObject.code,
                            problemMessage: newMessageText,
                            correctionMessage:
                                locatedMessage.messageObject.correctionMessage,
                            arguments: locatedMessage.messageObject.arguments)),
                    Severity.warning,
                    location: new Location(
                        message.uri!, message.line, message.column),
                    uriToSource: component.uriToSource),
                message.line,
                message.column,
                Severity.warning,
                []);
            onDiagnostic(message);
          }
        });
      });
    } else {
      int total = 0;
      forEachMessage(
          (String uri, Map<String, List<FormattedMessage>> actualMessagesMap) {
        int count = 0;
        actualMessagesMap
            .forEach((String message, List<FormattedMessage> actualMessages) {
          count += actualMessages.length;
        });

        print('${count} error(s) allowed in $uri');
        total += count;
      });
      if (total > 0) {
        print('${total} error(s) allowed in total.');
        print('Use option -v to see error details.');
      }
    }
  }

  void registerError(TreeNode node, String message) {
    registerMessage(node, message);
  }
}
