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

library _fe_analyzer_shared.messages.codes;

import 'dart:convert' show JsonEncoder, json;

import 'diagnostic_message.dart' show DiagnosticMessage;

import '../scanner/token.dart' show Token;

import 'severity.dart' show Severity;

import '../util/relativize.dart' as util show isWindows, relativizeUri;

part 'codes_generated.dart';

const int noLength = 1;

class Code<T> {
  final String name;

  /// The unique positive integer associated with this code,
  /// or `-1` if none. This index is used when translating
  /// this error to its corresponding Analyzer error.
  final int index;

  final List<String>? analyzerCodes;

  final Severity severity;

  const Code(this.name,
      {this.index: -1, this.analyzerCodes, this.severity: Severity.error});

  String toString() => name;
}

class Message {
  final Code<dynamic> code;

  final String message;

  final String? tip;

  final Map<String, dynamic> arguments;

  const Message(this.code,
      {required this.message, this.tip, this.arguments = const {}});

  LocatedMessage withLocation(Uri uri, int charOffset, int length) {
    return new LocatedMessage(uri, charOffset, length, this);
  }

  LocatedMessage withoutLocation() {
    return new LocatedMessage(null, -1, noLength, this);
  }

  String toString() {
    return "Message[$code, $message, $tip, $arguments]";
  }
}

class MessageCode extends Code<Null> implements Message {
  final String message;

  final String? tip;

  const MessageCode(String name,
      {int index: -1,
      List<String>? analyzerCodes,
      Severity severity: Severity.error,
      required this.message,
      this.tip})
      : super(name,
            index: index, analyzerCodes: analyzerCodes, severity: severity);

  Map<String, dynamic> get arguments => const <String, dynamic>{};

  Code<dynamic> get code => this;

  @override
  LocatedMessage withLocation(Uri uri, int charOffset, int length) {
    return new LocatedMessage(uri, charOffset, length, this);
  }

  LocatedMessage withoutLocation() {
    return new LocatedMessage(null, -1, noLength, this);
  }
}

class Template<T> {
  final String messageTemplate;

  final String? tipTemplate;

  final T withArguments;

  const Template(
      {required this.messageTemplate,
      this.tipTemplate,
      required this.withArguments});
}

class LocatedMessage implements Comparable<LocatedMessage> {
  final Uri? uri;

  final int charOffset;

  final int length;

  final Message messageObject;

  const LocatedMessage(
      this.uri, this.charOffset, this.length, this.messageObject);

  Code<dynamic> get code => messageObject.code;

  String get message => messageObject.message;

  String? get tip => messageObject.tip;

  Map<String, dynamic> get arguments => messageObject.arguments;

  @override
  int compareTo(LocatedMessage other) {
    int result = "${uri}".compareTo("${other.uri}");
    if (result != 0) return result;
    result = charOffset.compareTo(other.charOffset);
    if (result != 0) return result;
    return message.compareTo(message);
  }

  FormattedMessage withFormatting(String formatted, int line, int column,
      Severity severity, List<FormattedMessage> relatedInformation,
      {List<Uri>? involvedFiles}) {
    return new FormattedMessage(
        this, formatted, line, column, severity, relatedInformation,
        involvedFiles: involvedFiles);
  }

  @override
  int get hashCode =>
      13 * uri.hashCode +
      17 * charOffset.hashCode +
      19 * length.hashCode +
      23 * messageObject.hashCode;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is LocatedMessage &&
        uri == other.uri &&
        charOffset == other.charOffset &&
        length == other.length &&
        messageObject == other.messageObject;
  }

  @override
  String toString() =>
      'LocatedMessage(uri=$uri,charOffset=$charOffset,length=$length,'
      'messageObject=$messageObject)';
}

class FormattedMessage implements DiagnosticMessage {
  final LocatedMessage locatedMessage;

  final String formatted;

  final int line;

  final int column;

  @override
  final Severity severity;

  final List<FormattedMessage>? relatedInformation;

  final List<Uri>? involvedFiles;

  const FormattedMessage(this.locatedMessage, this.formatted, this.line,
      this.column, this.severity, this.relatedInformation,
      {this.involvedFiles});

  Code<dynamic> get code => locatedMessage.code;

  String get codeName => code.name;

  String get message => locatedMessage.message;

  String? get tip => locatedMessage.tip;

  Map<String, dynamic> get arguments => locatedMessage.arguments;

  Uri? get uri => locatedMessage.uri;

  int get charOffset => locatedMessage.charOffset;

  int get length => locatedMessage.length;

  @override
  Iterable<String> get ansiFormatted sync* {
    yield formatted;
    if (relatedInformation != null) {
      for (FormattedMessage m in relatedInformation!) {
        yield m.formatted;
      }
    }
  }

  @override
  Iterable<String> get plainTextFormatted {
    // TODO(ahe): Implement this correctly.
    return ansiFormatted;
  }

  Map<String, Object?> toJson() {
    // This should be kept in sync with package:kernel/problems.md
    return <String, Object?>{
      "ansiFormatted": ansiFormatted.toList(),
      "plainTextFormatted": plainTextFormatted.toList(),
      "severity": severity.index,
      "uri": uri?.toString(),
      "involvedFiles": involvedFiles?.map((u) => u.toString()).toList(),
      "codeName": code.name,
    };
  }

  String toJsonString() {
    JsonEncoder encoder = new JsonEncoder.withIndent("  ");
    return encoder.convert(this);
  }
}

class DiagnosticMessageFromJson implements DiagnosticMessage {
  @override
  final Iterable<String> ansiFormatted;

  @override
  final Iterable<String> plainTextFormatted;

  @override
  final Severity severity;

  final Uri? uri;

  final List<Uri>? involvedFiles;

  final String codeName;

  DiagnosticMessageFromJson(this.ansiFormatted, this.plainTextFormatted,
      this.severity, this.uri, this.involvedFiles, this.codeName);

  factory DiagnosticMessageFromJson.fromJson(String jsonString) {
    Map<String, Object> decoded = json.decode(jsonString);
    List<String> ansiFormatted =
        new List<String>.from(_asListOfString(decoded["ansiFormatted"]));
    List<String> plainTextFormatted =
        _asListOfString(decoded["plainTextFormatted"]);
    Severity severity = Severity.values[decoded["severity"] as int];
    Uri? uri =
        decoded["uri"] == null ? null : Uri.parse(decoded["uri"] as String);
    List<Uri>? involvedFiles = decoded["involvedFiles"] == null
        ? null
        : _asListOfString(decoded["involvedFiles"])
            .map((e) => Uri.parse(e))
            .toList();
    String codeName = decoded["codeName"] as String;

    return new DiagnosticMessageFromJson(ansiFormatted, plainTextFormatted,
        severity, uri, involvedFiles, codeName);
  }

  Map<String, Object?> toJson() {
    // This should be kept in sync with package:kernel/problems.md
    return <String, Object?>{
      "ansiFormatted": ansiFormatted.toList(),
      "plainTextFormatted": plainTextFormatted.toList(),
      "severity": severity.index,
      "uri": uri?.toString(),
      "involvedFiles": involvedFiles?.map((u) => u.toString()).toList(),
      "codeName": codeName,
    };
  }

  String toJsonString() {
    JsonEncoder encoder = new JsonEncoder.withIndent("  ");
    return encoder.convert(this);
  }

  static List<String> _asListOfString(Object? value) {
    return (value as List<dynamic>).cast<String>();
  }
}

String? relativizeUri(Uri? uri) {
  // We have this method here for two reasons:
  //
  // 1. It allows us to implement #uri message argument without using it
  // (otherwise, we might get an `UNUSED_IMPORT` warning).
  //
  // 2. We can change `base` argument here if needed.
  return uri == null ? null : util.relativizeUri(Uri.base, uri, util.isWindows);
}

typedef SummaryTemplate = Message Function(int, int, num, num, num);

String itemizeNames(List<String> names) {
  StringBuffer buffer = new StringBuffer();
  for (int i = 0; i < names.length - 1; i++) {
    buffer.write(" - ");
    buffer.writeln(names[i]);
  }
  buffer.write(" - ");
  buffer.write(names.last);
  return "$buffer";
}

/// Convert the synthetic name of an implicit mixin application class
/// into a name suitable for user-faced strings.
///
/// For example, when compiling "class A extends S with M1, M2", the
/// two synthetic classes will be named "_A&S&M1" and "_A&S&M1&M2".
/// This function will return "S with M1" and "S with M1, M2", respectively.
///
/// This method is copied from package:kernel/ast.dart.
// TODO(johnniwinther): Avoid the need for this method.
String demangleMixinApplicationName(String name) {
  List<String> nameParts = name.split('&');
  if (nameParts.length < 2 || name == "&") return name;
  String demangledName = nameParts[1];
  for (int i = 2; i < nameParts.length; i++) {
    demangledName += (i == 2 ? " with " : ", ") + nameParts[i];
  }
  return demangledName;
}

final RegExp templateKey = new RegExp(r'#(\w+)');

/// Replaces occurrences of '#key' in [template], where 'key' is a key in
/// [arguments], with the corresponding values.
String applyArgumentsToTemplate(
    String template, Map<String, dynamic> arguments) {
  // TODO(johnniwinther): Remove `as dynamic` when unsound null safety is
  // no longer supported.
  if (arguments as dynamic == null || arguments.isEmpty) {
    assert(!template.contains(templateKey),
        'Message requires arguments, but none were provided.');
    return template;
  }
  return template.replaceAllMapped(templateKey, (Match match) {
    String? key = match.group(1);
    Object? value = arguments[key];
    assert(value != null, "No value for '$key' found in $arguments");
    return value.toString();
  });
}
