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

/// Wrapper around ndk tools used for symbolization.
library symbolizer.ndk;

import 'dart:convert';
import 'dart:io';

import 'package:meta/meta.dart';
import 'package:path/path.dart' as p;

class Ndk {
  /// Return information about .text section from the given [object] file.
  Future<SectionInfo> getTextSectionInfo(String object) async {
    final result = await _run(_readelfBinary, ['-lW', object]);
    for (var match in _loadCommandPattern.allMatches(result)) {
      if (match.namedGroup('flags').trim() == 'R E') {
        // Found .text section
        return SectionInfo(
          fileOffset: int.parse(match.namedGroup('offset')),
          fileSize: int.parse(match.namedGroup('filesz')),
          virtualAddress: int.parse(match.namedGroup('vma')),
        );
      }
    }
    throw 'Failed to find LOAD command for text section in $object';
  }

  /// Return build-id of the given [object] file.
  Future<String> getBuildId(String object) async {
    final result = await _run(_readelfBinary, ['-nW', object]);
    final match = _buildIdPattern.firstMatch(result);
    if (match == null) {
      throw 'Failed to extract build-id from $object';
    }
    return match.namedGroup('id');
  }

  /// Symbolize given [addresses] using information available for the specified
  /// [arch] in the given [object] file.
  Future<List<String>> symbolize(
      {String object, List<String> addresses, String arch}) async {
    final result = await _run(_llvmSymbolizerBinary, [
      if (arch != null) '--default-arch=$arch',
      '--obj',
      object,
      '--inlines',
      ...addresses
    ]);

    final symbolized = result.replaceAllMapped(_builderPathPattern, (m) {
      return p.relative(p.normalize(m[0]),
          from: (m as RegExpMatch).namedGroup('root'));
    }).split('\n\n');
    if (symbolized.last == '') symbolized.length--;

    return symbolized;
  }

  /// Runs `llvm-objdump` on the given [object] and returns all lines produced
  /// by it.
  Stream<String> objdump({
    @required String object,
    @required String arch,
  }) async* {
    final process =
        await Process.start(_llvmObjdumpBinary, ['--arch=arm64', '-d', object]);

    await for (var line in process.stdout
        .transform(utf8.decoder)
        .transform(const LineSplitter())) {
      yield line;
    }
  }

  /// Run the given binary and return its stdout output if the run is
  /// successful. Otherwise throw an error.
  static Future<String> _run(String binary, List<String> args) async {
    final result = await Process.run(binary, args);
    if (result.exitCode != 0) {
      throw 'Failed to run ${p.basename(binary)} (${result.exitCode}):\nstdout:\n${result.stdout}\nstderr:\n${result.stderr}';
    }
    return result.stdout;
  }
}

/// Information about a section extracted from ELF file.
class SectionInfo {
  final int fileOffset;
  final int fileSize;
  final int virtualAddress;

  SectionInfo({
    @required this.fileOffset,
    @required this.fileSize,
    @required this.virtualAddress,
  });
}

final _platform = Platform.isLinux ? 'linux' : 'darwin';
final _ndkDir = 'tools/android-ndk';
final _llvmSymbolizerBinary =
    '${_ndkDir}/toolchains/llvm/prebuilt/$_platform-x86_64/bin/llvm-symbolizer';
final _llvmObjdumpBinary =
    '${_ndkDir}/toolchains/llvm/prebuilt/$_platform-x86_64/bin/llvm-objdump';
final _readelfBinary =
    '${_ndkDir}/toolchains/llvm/prebuilt/$_platform-x86_64/bin/x86_64-linux-android-readelf';
final _buildIdPattern = RegExp(r'Build ID:\s+(?<id>[0-9a-f]+)');
final _loadCommandPattern = RegExp(
    r'^\s+LOAD\s+(?<offset>0x[0-9a-f]+)\s+(?<vma>0x[0-9a-f]+)\s+(?<phys>0x[0-9a-f]+)\s+(?<filesz>0x[0-9a-f]+)\s+(?<memsz>0x[0-9a-f]+)\s+(?<flags>[^0]+)\s+0x[0-9a-f]+\s*$',
    multiLine: true);
final _builderPathPattern =
    RegExp(r'^(?<root>/(b|opt)/s/w/[\w/]+/src)/out/\S+', multiLine: true);
