#!/usr/bin/env dart
// Copyright (c) 2020, 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.

/// Primitive CLI for the symbolizer. Usage:
///
///    symbolize <input-file>|<github-uri> [overrides]
///

import 'dart:io';

import 'package:ansicolor/ansicolor.dart';
import 'package:github/github.dart';
import 'package:logging/logging.dart';
import 'package:path/path.dart' as p;

import 'package:symbolizer/model.dart';
import 'package:symbolizer/ndk.dart';
import 'package:symbolizer/symbolizer.dart';
import 'package:symbolizer/symbols.dart';

final githubIssueUriRe = RegExp(
    r'https://github.com/(?<org>[-\w]+)/(?<repo>[-\w]+)/issues/(?<issue>\d+)(?<anchor>#issue(comment)?-\d+)?');

Future<String> loadContent(GitHub github, String resource) async {
  final match = githubIssueUriRe.firstMatch(resource);
  if (match != null) {
    final orgName = match.namedGroup('org')!;
    final repoName = match.namedGroup('repo')!;
    final issueNumber = int.parse(match.namedGroup('issue')!);
    final anchor = match.namedGroup('anchor');

    final int? commentId;
    if (anchor != null && anchor.startsWith('#issuecomment-')) {
      commentId = int.parse(anchor.split('-').last);
    } else {
      commentId = null;
    }

    final slug = RepositorySlug(orgName, repoName);
    if (commentId != null) {
      final comment = await github.issues.getComment(slug, commentId);
      return comment.body ?? '';
    } else {
      final issue = await github.issues.get(slug, issueNumber);
      return issue.body;
    }
  } else {
    return File(resource).readAsString();
  }
}

void main(List<String> args) async {
  if (args.isEmpty ||
      args.length > 2 ||
      args.contains('-h') ||
      args.contains('--help')) {
    print('''
Usage: symbolize <file-or-uri> ["<overrides>"]

file-or-uri can be either a path to the local text file or a URI
pointing to an issue or an issue comment on GitHub.

Supported URI formats:
* https://github.com/<org>/<repo>/issues/<issuenum>
* https://github.com/<org>/<repo>/issues/<issuenum>#issue-<id>
* https://github.com/<org>/<repo>/issues/<issuenum>#issuecomment-<id>

Overrides argument can contain the following components:

* engine#<sha> - use specific engine commit
* flutter#<commit> - use specific flutter commit
* profile|release|debug - use specific build mode
* x86|arm|arm64|x64 - use specific engine architecture

Additionally you can specify:

* force ios - force symbolization of partial Mac OS / iOS / Crashlytics
              reports which don't contain all necessary markers. This
              forces symbolizer to look for frames like this:

              4  Flutter                        0x106013134 (Missing)

* internal - force symbolization of stacks which look like:

             0x0000000105340708(Flutter + 0x002b4708)
''');
    exit(1);
  }

  Logger.root.level = Level.ALL;
  Logger.root.onRecord.listen((record) {
    print('${record.level.name}: ${record.time}: ${record.message}');
  });

  final llvmTools = LlvmTools.findTools();
  if (llvmTools == null) {
    print('''
Failed to locate LLVM tools (llvm-{symbolizer,readobj,objdump}).

Either install them globally so that they are available in the \$PATH or
install Android NDK.
''');
    exit(1);
  }

  final ndk = Ndk(llvmTools: llvmTools);
  final symbols = SymbolsCache(
      path: p.join(Directory.systemTemp.path, 'symbols-cache'), ndk: ndk);
  final github = GitHub();

  final symbolizer = Symbolizer(symbols: symbols, ndk: ndk, github: github);

  try {
    final input = await loadContent(github, args.first);

    final overrides = args.length >= 2
        ? SymbolizationOverrides.tryParse(args.skip(1).join(' '))
        : null;

    _printResult(await symbolizer.symbolize(input, overrides: overrides));
  } finally {
    github.dispose();
  }
}

final errorPen = AnsiPen()..red();
final notePen = AnsiPen()..gray();
final successPen = AnsiPen()..green();
final stackPen = AnsiPen()..black(bold: true);

String _reindent(String str, {String padding = '  '}) {
  return '  ${str.split('\n').join('\n$padding')}';
}

/// Pretty print the given [SymbolizationResult] to stdout.
void _printResult(SymbolizationResult symbolized) async {
  final buf = StringBuffer();

  switch (symbolized) {
    case SymbolizationResultOk(:final results):
      for (var result in results) {
        buf.write('''

--------------------------------------------------------------------------------
''');
        bool success;
        switch (result) {
          case CrashSymbolizationResult(
              :final symbolized?,
              engineBuild: EngineBuild(
                engineHash: final engineHash,
                variant: EngineVariant(:final os, :final arch, :final mode)
              )
            ):
            success = true;
            buf.writeln(successPen(
                'symbolized using symbols for $engineHash $os-$arch-$mode\n'));
            buf.writeln(stackPen(_reindent(symbolized)));

          default:
            success = false;
            buf.writeln(errorPen('Found crash but failed to symbolize it.\n'));
            final addrSize = result.crash.frames
                    .map((frame) => frame.pc == (frame.pc & 0xFFFFFFFF))
                    .every((v) => v)
                ? 8
                : 16;

            for (var frame in result.crash.frames) {
              switch (frame) {
                case AndroidCrashFrame(
                    :final no,
                    :final pc,
                    :final binary,
                    :final rest,
                  ):
                  buf.writeln(stackPen(
                      '  #$no ${pc.toRadixString(16).padLeft(addrSize, '0')} $binary $rest'));

                default:
                  buf.writeln(stackPen('  ${frame.pc} ${frame.binary}'));
              }
            }
            buf.writeln();
        }

        final pen = success ? notePen : errorPen;
        for (var note in result.notes) {
          buf.write(pen('${noteMessage[note.kind]}'));
          final message = note.message;
          if (message != null && message.isNotEmpty) {
            buf.write(pen(':\n${_reindent(message)}'));
          }
          buf.write('');
        }

        buf.writeln('''

--------------------------------------------------------------------------------
''');
      }
    case SymbolizationResultError(error: final note):
      buf.write('''

--------------------------------------------------------------------------------
''');
      buf.write(errorPen('${noteMessage[note.kind]}'));
      final message = note.message;
      if (message != null && message.isNotEmpty) {
        buf.write(errorPen(':\n${_reindent(message)}'));
      }
      buf.write('');
      buf.writeln('''

--------------------------------------------------------------------------------
''');
  }

  print(buf);
}
