// Copyright (c) 2019, 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:async";
import "dart:convert";
import "dart:io" as io;

import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:path/path.dart' as path;
import 'package:native_stack_traces/native_stack_traces.dart';

ArgParser _createBaseDebugParser(ArgParser parser) => parser
  ..addOption('debug',
      abbr: 'd',
      help: 'Filename containing debugging information (REQUIRED)',
      valueHelp: 'FILE')
  ..addFlag('verbose',
      abbr: 'v',
      negatable: false,
      help: 'Translate all frames, not just user or library code frames')
  ..addFlag('dump_debug_file_contents',
      negatable: false,
      help: 'Dump all the parsed information from the debugging file');

final ArgParser _translateParser =
    _createBaseDebugParser(ArgParser(allowTrailingOptions: true))
      ..addOption('input',
          abbr: 'i', help: 'Filename for processed input', valueHelp: 'FILE')
      ..addOption('output',
          abbr: 'o', help: 'Filename for generated output', valueHelp: 'FILE');

final ArgParser _findParser =
    _createBaseDebugParser(ArgParser(allowTrailingOptions: true))
      ..addMultiOption('location',
          abbr: 'l', help: 'PC address to find', valueHelp: 'PC')
      ..addFlag('force_hexadecimal',
          abbr: 'x',
          negatable: false,
          help: 'Always parse integers as hexadecimal')
      ..addOption('vm_start',
          help: 'Absolute address for start of VM instructions',
          valueHelp: 'PC')
      ..addOption('isolate_start',
          help: 'Absolute address for start of isolate instructions',
          valueHelp: 'PC');

final ArgParser _helpParser = ArgParser(allowTrailingOptions: true);

final ArgParser _argParser = ArgParser(allowTrailingOptions: true)
  ..addCommand('help', _helpParser)
  ..addCommand('find', _findParser)
  ..addCommand('translate', _translateParser)
  ..addFlag('help',
      abbr: 'h',
      negatable: false,
      help: 'Print usage information for this or a particular subcommand');

final String _mainUsage = '''
Usage: decode <command> [options] ...

Commands:
${_argParser.commands.keys.join("\n")}

Options shared by all commands:
${_argParser.usage}''';

final String _helpUsage = '''
Usage: decode help [<command>]

Returns usage for the decode utility or a particular command.

Commands:
${_argParser.commands.keys.join("\n")}''';

final String _translateUsage = '''
Usage: decode translate [options]

The translate command takes text that includes non-symbolic stack traces
generated by the VM when executing a snapshot compiled with the
--dwarf-stack-traces flag. It outputs almost the same text, but with any
non-symbolic stack traces converted to symbolic stack traces that contain
function names, file names, and line numbers.

Options shared by all commands:
${_argParser.usage}

Options specific to the translate command:
${_translateParser.usage}''';

final String _findUsage = '''
Usage: decode find [options] <PC> ...

The find command looks up program counter (PC) addresses, either given as
arguments on the command line or via the -l/--location option. For each
successful PC lookup, it outputs the call information in one of two formats:

- If the location corresponds to a call site in Dart source code, the call
  information includes the file, function, and line number information.
- If it corresponds to a Dart VM stub, the call information includes the dynamic
  symbol name for the instructions payload and an offset into that payload.

The -l option may be provided multiple times, or a single use of the -l option
may be given multiple arguments separated by commas.

PC addresses can be provided in one of two formats:

- An integer, e.g. 0x2a3f or 15049
- A static symbol in the VM snapshot plus an integer offset, e.g.,
  _kDartIsolateSnapshotInstructions+1523 or _kDartVMSnapshotInstructions+0x403f

Integers without an "0x" prefix that do not includes hexadecimal digits are
assumed to be decimal unless the -x/--force_hexadecimal flag is used.

By default, integer PC addresses are assumed to be virtual addresses valid for
the given debugging information. Otherwise, use both the --vm_start and
--isolate_start arguments to provide the appropriate starting addresses of the
VM and isolate instructions sections.

Options shared by all commands:
${_argParser.usage}

Options specific to the find command:
${_findParser.usage}''';

final _usages = <String, String>{
  null: _mainUsage,
  '': _mainUsage,
  'help': _helpUsage,
  'translate': _translateUsage,
  'find': _findUsage,
};

const int _badUsageExitCode = 1;

void errorWithUsage(String message, {String command}) {
  print("Error: $message.\n");
  print(_usages[command]);
  io.exitCode = _badUsageExitCode;
}

void help(ArgResults options) {
  void usageError(String message) => errorWithUsage(message, command: 'help');

  switch (options.rest.length) {
    case 0:
      return print(_usages['help']);
    case 1:
      {
        final usage = _usages[options.rest.first];
        if (usage != null) return print(usage);
        return usageError('invalid command ${options.rest.first}');
      }
    default:
      return usageError('too many arguments');
  }
}

Dwarf _loadFromFile(String original, Function(String) usageError) {
  if (original == null) {
    usageError('must provide -d/--debug');
    return null;
  }
  final filename = path.canonicalize(path.normalize(original));
  if (!io.File(filename).existsSync()) {
    usageError('debug file "$original" does not exist');
    return null;
  }
  final dwarf = Dwarf.fromFile(filename);
  if (dwarf == null) {
    usageError('file "$original" does not contain debugging information');
  }
  return dwarf;
}

void find(ArgResults options) {
  final bool verbose = options['verbose'];
  final bool forceHexadecimal = options['force_hexadecimal'];

  void usageError(String message) => errorWithUsage(message, command: 'find');
  int parseIntAddress(String s) {
    if (!forceHexadecimal && !s.startsWith("0x")) {
      final decimal = int.tryParse(s);
      if (decimal != null) return decimal;
    }
    return int.tryParse(s.startsWith("0x") ? s.substring(2) : s, radix: 16);
  }

  PCOffset convertAddress(StackTraceHeader header, String s) {
    final parsedOffset = tryParseSymbolOffset(s, forceHexadecimal);
    if (parsedOffset != null) return parsedOffset;

    final address = parseIntAddress(s);
    if (address != null) return header.offsetOf(address);

    return null;
  }

  final dwarf = _loadFromFile(options['debug'], usageError);
  if (dwarf == null) return;

  if (options['dump_debug_file_contents']) {
    print(dwarf.dumpFileInfo());
  }

  if ((options['vm_start'] == null) != (options['isolate_start'] == null)) {
    return usageError("need both VM start and isolate start");
  }

  int vmStart = dwarf.vmStartAddress;
  if (options['vm_start'] != null) {
    vmStart = parseIntAddress(options['vm_start']);
    if (vmStart == null) {
      return usageError('could not parse VM start address '
          '${options['vm_start']}');
    }
  }

  int isolateStart = dwarf.isolateStartAddress;
  if (options['isolate_start'] != null) {
    isolateStart = parseIntAddress(options['isolate_start']);
    if (isolateStart == null) {
      return usageError('could not parse isolate start address '
          '${options['isolate_start']}');
    }
  }

  final header = StackTraceHeader(isolateStart, vmStart);

  final locations = <PCOffset>[];
  for (final String s in options['location'] + options.rest) {
    final location = convertAddress(header, s);
    if (location == null) return usageError('could not parse PC address ${s}');
    locations.add(location);
  }
  if (locations.isEmpty) return usageError('no PC addresses to find');

  for (final offset in locations) {
    final addr = dwarf.virtualAddressOf(offset);
    final frames = dwarf
        .callInfoFor(addr, includeInternalFrames: verbose)
        ?.map((CallInfo c) => "  " + c.toString());
    final addrString =
        addr > 0 ? "0x" + addr.toRadixString(16) : addr.toString();
    print("For virtual address ${addrString}:");
    if (frames == null) {
      print("  Invalid virtual address.");
    } else if (frames.isEmpty) {
      print("  Not a call from user or library code.");
    } else {
      frames.forEach(print);
    }
  }
}

Future<void> translate(ArgResults options) async {
  void usageError(String message) =>
      errorWithUsage(message, command: 'translate');

  final dwarf = _loadFromFile(options['debug'], usageError);
  if (dwarf == null) {
    return;
  }
  if (options['dump_debug_file_contents']) {
    print(dwarf.dumpFileInfo());
  }

  final verbose = options['verbose'];
  final output = options['output'] != null
      ? io.File(path.canonicalize(path.normalize(options['output'])))
          .openWrite()
      : io.stdout;
  final input = options['input'] != null
      ? io.File(path.canonicalize(path.normalize(options['input']))).openRead()
      : io.stdin;

  final convertedStream = input
      .transform(utf8.decoder)
      .transform(const LineSplitter())
      .transform(DwarfStackTraceDecoder(dwarf, includeInternalFrames: verbose))
      .map((s) => s + "\n")
      .transform(utf8.encoder);

  await output.addStream(convertedStream);
  await output.flush();
  await output.close();
}

Future<void> main(List<String> arguments) async {
  ArgResults options;

  try {
    options = _argParser.parse(arguments);
  } on FormatException catch (e) {
    return errorWithUsage(e.message);
  }

  if (options['help']) return print(_usages[options.command?.name]);
  if (options.command == null) return errorWithUsage('no command provided');

  switch (options.command.name) {
    case 'help':
      return help(options.command);
    case 'find':
      return find(options.command);
    case 'translate':
      return await translate(options.command);
  }
}
