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

/// Logic to deobfuscate minified names that appear in error messages.

import 'package:source_maps/source_maps.dart';

import 'dart2js_mapping.dart';
import 'trace.dart';

String? translate(String? error, Dart2jsMapping? mapping,
    [StackTraceLine? line, TargetEntry? entry]) {
  for (var decoder in _errorMapDecoders) {
    var result = decoder.decode(error, mapping, line, entry);
    // More than one decoder might be applied on a single error message. This
    // can be useful, for example, if an error contains details about a member
    // and the type.
    if (result != null) error = result;
  }
  return error;
}

/// A decoder that matches an error against a regular expression and
/// uses data from the source-file and source-map file to translate minified
/// names to un-minified names.
abstract class ErrorMapDecoder {
  RegExp get _matcher;

  /// Decode [error] that was reported in [line] and has a corresponding [entry]
  /// in the source-map file. The provided [mapping] includes additional
  /// minification data that may be used to decode the error message.
  String? decode(String? error, Dart2jsMapping? mapping, StackTraceLine? line,
      TargetEntry? entry) {
    if (error == null) return null;
    Match? lastMatch = null;
    var result = new StringBuffer();
    for (var match in _matcher.allMatches(error)) {
      var decodedMatch = _decodeInternal(match, mapping, line, entry);
      if (decodedMatch == null) {
        continue;
      }
      result.write(error.substring(lastMatch?.end ?? 0, match.start));
      result.write(decodedMatch);
      lastMatch = match;
    }
    if (lastMatch == null) return null;
    result.write(error.substring(lastMatch.end, error.length));
    return '$result';
  }

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry);
}

typedef String ErrorDecoder(Match match, Dart2jsMapping mapping,
    StackTraceLine line, TargetEntry entry);

class MinifiedNameDecoder extends ErrorMapDecoder {
  final RegExp _matcher = new RegExp("minified:([a-zA-Z0-9_\$]*)");

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry) {
    var minifiedName = match.group(1);
    return mapping!.globalNames[minifiedName];
  }
}

class CannotReadPropertyDecoder extends ErrorMapDecoder {
  final RegExp _matcher = new RegExp("Cannot read property '([^']*)' of");

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry) {
    var minifiedName = match.group(1);
    var name = mapping!.instanceNames[minifiedName];
    if (name == null) return null;
    return "Cannot read property '$name' of";
  }
}

abstract class NoSuchMethodDecoderBase extends ErrorMapDecoder {
  String? _translateMinifiedName(Dart2jsMapping mapping, String? minifiedName) {
    var name = mapping.instanceNames[minifiedName];
    if (name != null) return "'$name'";
    if (minifiedName!.startsWith(new RegExp(r'(call)?\$[0-9]'))) {
      int first$ = minifiedName.indexOf(r'$');
      return _expandCallSignature(minifiedName.substring(first$));
    }
    return null;
  }

  String? _expandCallSignature(String callSignature) {
    // Minified names are one of these forms:
    //   $0         // positional arguments only
    //   $1$2       // type parameters and positional arguments
    //   $3$name    // positional and named arguments
    //   $1$3$name  // type parameters and positional and named args
    var signature = callSignature.split(r'$');
    int? typeArgs = null;
    int? totalArgs = null;
    var namedArgs = <String>[];
    for (var arg in signature) {
      if (arg == "") continue;
      var count = int.tryParse(arg);
      if (count != null) {
        if (totalArgs != null) {
          if (typeArgs != null) {
            // unexpected format, leave it unchanged.
            return null;
          }
          typeArgs = totalArgs;
        }
        totalArgs = count;
      } else {
        namedArgs.add(arg);
      }
    }
    if (totalArgs == null) return null;
    var sb = new StringBuffer();
    sb.write("'call'");
    sb.write(" (with ");
    if (typeArgs != null) {
      sb.write("$typeArgs type arguments");
      sb.write(namedArgs.isNotEmpty ? ", " : " and ");
    }
    sb.write("${totalArgs - namedArgs.length} positional arguments");
    if (namedArgs.isNotEmpty) {
      sb.write(typeArgs != null ? "," : "");
      sb.write(" and named arguments '${namedArgs.join("', '")}'");
    }
    sb.write(')');
    return "$sb";
  }
}

class NoSuchMethodDecoder1 extends NoSuchMethodDecoderBase {
  final RegExp _matcher = new RegExp(
      "NoSuchMethodError: method not found: '([^']*)'( on [^\\(]*)? \\(.*\\)");

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry) {
    var minifiedName = match.group(1);
    var suffix = match.group(2) ?? '';
    var name = _translateMinifiedName(mapping!, minifiedName);
    if (name == null) return null;
    return "NoSuchMethodError: method not found: $name$suffix";
  }
}

class NoSuchMethodDecoder2 extends NoSuchMethodDecoderBase {
  final RegExp _matcher =
      new RegExp("NoSuchMethodError: method not found: '([^']*)'");

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry) {
    var minifiedName = match.group(1);
    var name = _translateMinifiedName(mapping!, minifiedName);
    if (name == null) return null;
    return "NoSuchMethodError: method not found: $name";
  }
}

class UnhandledNotAFunctionError extends ErrorMapDecoder {
  final RegExp _matcher = new RegExp("Error: ([^']*) is not a function");

  String? _decodeInternal(Match match, Dart2jsMapping? mapping,
      StackTraceLine? line, TargetEntry? entry) {
    var minifiedName = match.group(1);
    var name = mapping!.instanceNames[minifiedName];
    if (name == null) return null;
    return "Error: $name is not a function";
  }
}

List<ErrorMapDecoder> _errorMapDecoders = [
  new MinifiedNameDecoder(),
  new CannotReadPropertyDecoder(),
  new NoSuchMethodDecoder1(),
  new NoSuchMethodDecoder2(),
  new UnhandledNotAFunctionError(),
];
