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