// 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(PlainAndColorizedString formatted, int line,
      int column, Severity severity, List<FormattedMessage>? relatedInformation,
      {List<Uri>? involvedFiles}) {
    return new FormattedMessage(this, formatted.plain, formatted.colorized,
        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 PlainAndColorizedString {
  final String plain;
  final String colorized;

  @override
  String toString() {
    assert(false, "Called PlainAndColorizedString.toString: $plain");
    return 'PlainAndColorizedString:$plain';
  }

  const PlainAndColorizedString(this.plain, this.colorized);

  const PlainAndColorizedString.plainOnly(this.plain) : this.colorized = plain;
}

class FormattedMessage implements DiagnosticMessage {
  final LocatedMessage locatedMessage;

  final String formattedPlain;

  final String formattedColorized;

  final int line;

  final int column;

  @override
  final Severity severity;

  final List<FormattedMessage>? relatedInformation;

  final List<Uri>? involvedFiles;

  const FormattedMessage(
      this.locatedMessage,
      this.formattedPlain,
      this.formattedColorized,
      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 formattedColorized;
    if (relatedInformation != null) {
      for (FormattedMessage m in relatedInformation!) {
        yield m.formattedColorized;
      }
    }
  }

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

  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();
  });
}
