// 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.

import 'dart:io';
import 'dart:math' show max;
import 'package:stack_trace/stack_trace.dart';
import 'package:dart2js_tools/src/trace.dart';
import 'package:dart2js_tools/src/name_decoder.dart';
import 'package:dart2js_tools/src/util.dart';
import 'package:dart2js_tools/src/trace_decoder.dart';

/// Script that deobfuscates a stack-trace given in a text file.
///
/// To run this script you need 3 or more files:
///
///  * A stacktrace file
///  * The deployed .js file
///  * The corresponding .map file
///
/// There might be more than one .js/.map file if your app is divided in
/// deferred chunks.
///
/// The stack trace file contains a copy/paste of a JavaScript stack trace, of
/// this form:
///
///     at aB.a20 (main.dart.js:71969:32)
///     at aNk.goV (main.dart.js:72040:52)
///     at aNk.gfK (main.dart.js:72038:27)
///     at FE.gtn (main.dart.js:72640:24)
///     at aBZ.ghN (main.dart.js:72642:24)
///     at inheritance (main.dart.js:105334:0)
///     at FE (main.dart.js:5037:18)
///
/// If you download the stacktrace from a production service, you can keep the
/// full URL (including http://....) and this script will simply try to match
/// the name of the file at the end with a file in the current working
/// directory.
///
/// The .js file must contain a `//# sourceMappingURL=` line at the end, which
/// tells this script how to determine the name of the source-map file.
main(List<String> args) {
  if (args.length != 1) {
    print('usage: deobfuscate.dart <stack-trace-file>');
    exit(1);
  }
  var sb = new StringBuffer();
  try {
    String obfuscatedTrace = new File(args[0]).readAsStringSync();
    String? error = extractErrorMessage(obfuscatedTrace);
    var provider = new CachingFileProvider(logger: Logger());
    StackDeobfuscationResult result =
        deobfuscateStack(obfuscatedTrace, provider);
    Frame firstFrame = result.original.frames.first;
    String? translatedError =
        translate(error, provider.mappingFor(firstFrame.uri));
    if (translatedError == null) translatedError = '<no error message found>';
    printPadded(translatedError, error, sb);
    int longest =
        result.deobfuscated.frames.fold(0, (m, f) => max(f.member!.length, m));
    for (var originalFrame in result.original.frames) {
      var deobfuscatedFrames = result.frameMap[originalFrame];
      if (deobfuscatedFrames == null) {
        printPadded('no mapping', '${originalFrame.location}', sb);
      } else {
        for (var frame in deobfuscatedFrames) {
          printPadded('${frame.member!.padRight(longest)} ${frame.location}',
              '${originalFrame.location}', sb);
        }
      }
    }
  } finally {
    print('$sb');
  }
}

final green = stdout.hasTerminal ? '\x1b[32m' : '';
final none = stdout.hasTerminal ? '\x1b[0m' : '';

printPadded(String mapping, String? original, sb) {
  var len = mapping.length;
  var s = mapping.indexOf('\n');
  if (s >= 0) len -= s + 1;
  var pad = ' ' * (50 - len);
  sb.writeln('$green$mapping$none$pad ... $original');
}
