#!/usr/bin/env python3
#
# Copyright (C) 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""utils.py: export utility functions.
"""

from __future__ import annotations
import argparse
from concurrent.futures import Future, ThreadPoolExecutor
from dataclasses import dataclass
import logging
import os
import os.path
from pathlib import Path
import re
import shutil
import subprocess
import sys
import time
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Union


NDK_ERROR_MESSAGE = "Please install the Android NDK (https://developer.android.com/studio/projects/install-ndk), then set NDK path with --ndk_path option."


def get_script_dir() -> str:
    return os.path.dirname(os.path.realpath(__file__))


def is_windows() -> bool:
    return sys.platform == 'win32' or sys.platform == 'cygwin'


def is_darwin() -> bool:
    return sys.platform == 'darwin'


def get_platform() -> str:
    if is_windows():
        return 'windows'
    if is_darwin():
        return 'darwin'
    return 'linux'


def str_to_bytes(str_value: str) -> bytes:
    # In python 3, str are wide strings whereas the C api expects 8 bit strings,
    # hence we have to convert. For now using utf-8 as the encoding.
    return str_value.encode('utf-8')


def bytes_to_str(bytes_value: Optional[bytes]) -> str:
    if not bytes_value:
        return ''
    return bytes_value.decode('utf-8')


def get_target_binary_path(arch: str, binary_name: str) -> str:
    if arch == 'aarch64':
        arch = 'arm64'
    arch_dir = os.path.join(get_script_dir(), "bin", "android", arch)
    if not os.path.isdir(arch_dir):
        log_fatal("can't find arch directory: %s" % arch_dir)
    binary_path = os.path.join(arch_dir, binary_name)
    if not os.path.isfile(binary_path):
        log_fatal("can't find binary: %s" % binary_path)
    return binary_path


def get_host_binary_path(binary_name: str) -> str:
    dirname = os.path.join(get_script_dir(), 'bin')
    if is_windows():
        if binary_name.endswith('.so'):
            binary_name = binary_name[0:-3] + '.dll'
        elif '.' not in binary_name:
            binary_name += '.exe'
        dirname = os.path.join(dirname, 'windows')
    elif sys.platform == 'darwin':  # OSX
        if binary_name.endswith('.so'):
            binary_name = binary_name[0:-3] + '.dylib'
        dirname = os.path.join(dirname, 'darwin')
    else:
        dirname = os.path.join(dirname, 'linux')
    dirname = os.path.join(dirname, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
    binary_path = os.path.join(dirname, binary_name)
    if not os.path.isfile(binary_path):
        log_fatal("can't find binary: %s" % binary_path)
    return binary_path


def is_executable_available(executable: str, option='--help') -> bool:
    """ Run an executable to see if it exists. """
    try:
        subproc = subprocess.Popen([executable, option], stdout=subprocess.PIPE,
                                   stderr=subprocess.PIPE)
        subproc.communicate()
        return subproc.returncode == 0
    except OSError:
        return False


class ToolFinder:
    """ Find tools in ndk or sdk. """
    DEFAULT_SDK_PATH = {
        'darwin': 'Library/Android/sdk',
        'linux': 'Android/Sdk',
        'windows': 'AppData/Local/Android/sdk',
    }

    EXPECTED_TOOLS = {
        'adb': {
            'is_binutils': False,
            'test_option': 'version',
            'path_in_sdk': 'platform-tools/adb',
        },
        'llvm-objdump': {
            'is_binutils': False,
            'path_in_ndk':
                lambda platform: 'toolchains/llvm/prebuilt/%s-x86_64/bin/llvm-objdump' % platform,
        },
        'llvm-readelf': {
            'is_binutils': False,
            'path_in_ndk':
                lambda platform: 'toolchains/llvm/prebuilt/%s-x86_64/bin/llvm-readelf' % platform,
        },
        'llvm-symbolizer': {
            'is_binutils': False,
            'path_in_ndk':
                lambda platform: 'toolchains/llvm/prebuilt/%s-x86_64/bin/llvm-symbolizer' % platform,
        },
        'llvm-strip': {
            'is_binutils': False,
            'path_in_ndk':
                lambda platform: 'toolchains/llvm/prebuilt/%s-x86_64/bin/llvm-strip' % platform,
        },
    }

    @classmethod
    def find_ndk_and_sdk_paths(cls, ndk_path: Optional[str] = None
                               ) -> Iterator[Tuple[Optional[str], Optional[str]]]:
        # Use the given ndk path.
        if ndk_path and os.path.isdir(ndk_path):
            ndk_path = os.path.abspath(ndk_path)
            yield ndk_path, cls.find_sdk_path(ndk_path)
        # Find ndk in the parent directory containing simpleperf scripts.
        ndk_path = os.path.dirname(os.path.abspath(get_script_dir()))
        yield ndk_path, cls.find_sdk_path(ndk_path)
        # Find ndk in the default sdk installation path.
        if is_windows():
            home = os.environ.get('HOMEDRIVE') + os.environ.get('HOMEPATH')
        else:
            home = os.environ.get('HOME')
        if home:
            platform = get_platform()
            sdk_path = os.path.join(home, cls.DEFAULT_SDK_PATH[platform].replace('/', os.sep))
            if os.path.isdir(sdk_path):
                path = os.path.join(sdk_path, 'ndk')
                if os.path.isdir(path):
                    # Android Studio can install multiple ndk versions in 'ndk'.
                    # Find the newest one.
                    ndk_version = None
                    for name in os.listdir(path):
                        if not ndk_version or ndk_version < name:
                            ndk_version = name
                    if ndk_version:
                        yield os.path.join(path, ndk_version), sdk_path
            ndk_path = os.path.join(sdk_path, 'ndk-bundle')
            if os.path.isdir(ndk_path):
                yield ndk_path, sdk_path

    @classmethod
    def find_sdk_path(cls, ndk_path: str) -> Optional[str]:
        path = ndk_path
        for _ in range(2):
            path = os.path.dirname(path)
            if os.path.isdir(os.path.join(path, 'platform-tools')):
                return path
        return None

    @classmethod
    def _get_binutils_path_in_ndk(cls, toolname: str, arch: Optional[str], platform: str
                                  ) -> Tuple[str, str]:
        if not arch:
            arch = 'arm64'
        if arch == 'arm64':
            name = 'aarch64-linux-android-' + toolname
        elif arch == 'arm':
            name = 'arm-linux-androideabi-' + toolname
        elif arch == 'x86_64':
            name = 'x86_64-linux-android-' + toolname
        elif arch == 'x86':
            name = 'i686-linux-android-' + toolname
        else:
            log_fatal('unexpected arch %s' % arch)
        path = 'toolchains/llvm/prebuilt/%s-x86_64/bin/%s' % (platform, name)
        return (name, path)

    @classmethod
    def find_tool_path(cls, toolname: str, ndk_path: Optional[str] = None,
                       arch: Optional[str] = None) -> Optional[str]:
        tool_info = cls.EXPECTED_TOOLS.get(toolname)
        if not tool_info:
            return None

        is_binutils = tool_info['is_binutils']
        test_option = tool_info.get('test_option', '--help')
        platform = get_platform()

        # Find tool in clang prebuilts in Android platform.
        if toolname.startswith('llvm-') and platform == 'linux' and get_script_dir().endswith(
                'system/extras/simpleperf/scripts'):
            path = str(
                Path(get_script_dir()).parents[3] / 'prebuilts' / 'clang' / 'host' / 'linux-x86' /
                'llvm-binutils-stable' / toolname)
            if is_executable_available(path, test_option):
                return path

        # Find tool in NDK or SDK.
        path_in_ndk = None
        path_in_sdk = None
        if is_binutils:
            toolname_with_arch, path_in_ndk = cls._get_binutils_path_in_ndk(
                toolname, arch, platform)
        else:
            toolname_with_arch = toolname
            if 'path_in_ndk' in tool_info:
                path_in_ndk = tool_info['path_in_ndk'](platform)
            elif 'path_in_sdk' in tool_info:
                path_in_sdk = tool_info['path_in_sdk']
        if path_in_ndk:
            path_in_ndk = path_in_ndk.replace('/', os.sep)
        elif path_in_sdk:
            path_in_sdk = path_in_sdk.replace('/', os.sep)

        for ndk_dir, sdk_dir in cls.find_ndk_and_sdk_paths(ndk_path):
            if path_in_ndk and ndk_dir:
                path = os.path.join(ndk_dir, path_in_ndk)
                if is_executable_available(path, test_option):
                    return path
            elif path_in_sdk and sdk_dir:
                path = os.path.join(sdk_dir, path_in_sdk)
                if is_executable_available(path, test_option):
                    return path

        # Find tool in $PATH.
        if is_executable_available(toolname_with_arch, test_option):
            return toolname_with_arch

        # Find tool without arch in $PATH.
        if is_binutils and tool_info.get('accept_tool_without_arch'):
            if is_executable_available(toolname, test_option):
                return toolname
        return None


class AdbHelper(object):
    def __init__(self, enable_switch_to_root: bool = True):
        adb_path = ToolFinder.find_tool_path('adb')
        if not adb_path:
            log_exit("Can't find adb in PATH environment.")
        self.adb_path: str = adb_path
        self.enable_switch_to_root = enable_switch_to_root
        self.serial_number: Optional[str] = None

    def is_device_available(self) -> bool:
        return self.run_and_return_output(['shell', 'whoami'])[0]

    def run(self, adb_args: List[str], log_output: bool = False, log_stderr: bool = False) -> bool:
        return self.run_and_return_output(adb_args, log_output, log_stderr)[0]

    def run_and_return_output(self, adb_args: List[str], log_output: bool = False,
                              log_stderr: bool = False) -> Tuple[bool, str]:
        adb_args = [self.adb_path] + adb_args
        logging.debug('run adb cmd: %s' % adb_args)
        env = None
        if self.serial_number:
            env = os.environ.copy()
            env['ANDROID_SERIAL'] = self.serial_number
        subproc = subprocess.Popen(
            adb_args, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout_data, stderr_data = subproc.communicate()
        stdout_data = bytes_to_str(stdout_data)
        stderr_data = bytes_to_str(stderr_data)
        returncode = subproc.returncode
        result = (returncode == 0)
        if log_output and stdout_data:
            logging.debug(stdout_data)
        if log_stderr and stderr_data:
            logging.warning(stderr_data)
        logging.debug('run adb cmd: %s  [result %s]' % (adb_args, result))
        return (result, stdout_data)

    def check_run(self, adb_args: List[str], log_output: bool = False):
        self.check_run_and_return_output(adb_args, log_output)

    def check_run_and_return_output(self, adb_args: List[str], log_output: bool = False,
                                    log_stderr: bool = False) -> str:
        result, stdoutdata = self.run_and_return_output(adb_args, log_output, True)
        if not result:
            log_exit('run "adb %s" failed: %s' % (adb_args, stdoutdata))
        return stdoutdata

    def _unroot(self):
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        if not result:
            return
        if 'root' not in stdoutdata:
            return
        logging.info('unroot adb')
        self.run(['unroot'])
        time.sleep(1)
        self.run(['wait-for-device'])

    def switch_to_root(self) -> bool:
        if not self.enable_switch_to_root:
            self._unroot()
            return False
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        if not result:
            return False
        if 'root' in stdoutdata:
            return True
        build_type = self.get_property('ro.build.type')
        if build_type == 'user':
            return False
        self.run(['root'])
        time.sleep(1)
        self.run(['wait-for-device'])
        result, stdoutdata = self.run_and_return_output(['shell', 'whoami'])
        return result and 'root' in stdoutdata

    def get_property(self, name: str) -> Optional[str]:
        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
        return stdoutdata.strip() if result else None

    def set_property(self, name: str, value: str) -> bool:
        return self.run(['shell', 'setprop', name, value])

    def get_device_arch(self) -> str:
        output = self.check_run_and_return_output(['shell', 'uname', '-m'])
        if 'aarch64' in output:
            return 'arm64'
        if 'arm' in output:
            return 'arm'
        if 'x86_64' in output:
            return 'x86_64'
        if '86' in output:
            return 'x86'
        log_fatal('unsupported architecture: %s' % output.strip())
        return ''

    def get_android_version(self) -> int:
        """ Get Android version on device, like 7 is for Android N, 8 is for Android O."""
        build_version = self.get_property('ro.build.version.codename')
        if not build_version or build_version == 'REL':
            build_version = self.get_property('ro.build.version.release')
        android_version = 0
        if build_version:
            if build_version[0].isdigit():
                i = 1
                while i < len(build_version) and build_version[i].isdigit():
                    i += 1
                android_version = int(build_version[:i])
            else:
                c = build_version[0].upper()
                if c.isupper() and c >= 'L':
                    android_version = ord(c) - ord('L') + 5
        return android_version


def flatten_arg_list(arg_list: List[List[str]]) -> List[str]:
    res = []
    if arg_list:
        for items in arg_list:
            res += items
    return res


def remove(dir_or_file: Union[Path, str]):
    if os.path.isfile(dir_or_file):
        os.remove(dir_or_file)
    elif os.path.isdir(dir_or_file):
        shutil.rmtree(dir_or_file, ignore_errors=True)


def open_report_in_browser(report_path: str):
    if is_darwin():
        # On darwin 10.12.6, webbrowser can't open browser, so try `open` cmd first.
        try:
            subprocess.check_call(['open', report_path])
            return
        except subprocess.CalledProcessError:
            pass
    import webbrowser
    try:
        # Try to open the report with Chrome
        browser = webbrowser.get('google-chrome')
        browser.open(report_path, new=0, autoraise=True)
    except webbrowser.Error:
        # webbrowser.get() doesn't work well on darwin/windows.
        webbrowser.open_new_tab(report_path)


class BinaryFinder:
    def __init__(self, binary_cache_dir: Optional[Union[Path, str]], readelf: ReadElf):
        if isinstance(binary_cache_dir, str):
            binary_cache_dir = Path(binary_cache_dir)
        self.binary_cache_dir = binary_cache_dir
        self.readelf = readelf
        self.build_id_map = self._load_build_id_map()

    def _load_build_id_map(self) -> Dict[str, Path]:
        build_id_map: Dict[str, Path] = {}
        if self.binary_cache_dir:
            build_id_list_file = self.binary_cache_dir / 'build_id_list'
            if build_id_list_file.is_file():
                with open(self.binary_cache_dir / 'build_id_list', 'rb') as fh:
                    for line in fh.readlines():
                        # lines are in format "<build_id>=<path_in_binary_cache>".
                        items = bytes_to_str(line).strip().split('=')
                        if len(items) == 2:
                            build_id_map[items[0]] = self.binary_cache_dir / items[1]
        return build_id_map

    def find_binary(self, dso_path_in_record_file: str,
                    expected_build_id: Optional[str]) -> Optional[Path]:
        """ If expected_build_id is None, don't check build id.
            Otherwise, the build id of the found binary should match the expected one."""
        # Find binary from build id map.
        if expected_build_id:
            path = self.build_id_map.get(expected_build_id)
            if path and self._check_path(path, expected_build_id):
                return path
        # Find binary by path in binary cache.
        if self.binary_cache_dir:
            path = self.binary_cache_dir / dso_path_in_record_file[1:].replace('/', os.sep)
            if self._check_path(path, expected_build_id):
                return path
        # Find binary by its absolute path.
        path = Path(dso_path_in_record_file)
        if self._check_path(path, expected_build_id):
            return path
        return None

    def _check_path(self, path: Path, expected_build_id: Optional[str]) -> bool:
        if not self.readelf.is_elf_file(path):
            return False
        if expected_build_id is not None:
            return self.readelf.get_build_id(path) == expected_build_id
        return True


class Addr2Nearestline(object):
    """ Use llvm-symbolizer to convert (dso_path, func_addr, addr) to (source_file, line).
        For instructions generated by C++ compilers without a matching statement in source code
        (like stack corruption check, switch optimization, etc.), addr2line can't generate
        line information. However, we want to assign the instruction to the nearest line before
        the instruction (just like objdump -dl). So we use below strategy:
        Instead of finding the exact line of the instruction in an address, we find the nearest
        line to the instruction in an address. If an address doesn't have a line info, we find
        the line info of address - 1. If still no line info, then use address - 2, address - 3,
        etc.

        The implementation steps are as below:
        1. Collect all (dso_path, func_addr, addr) requests before converting. This saves the
        times to call addr2line.
        2. Convert addrs to (source_file, line) pairs for each dso_path as below:
          2.1 Check if the dso_path has .debug_line. If not, omit its conversion.
          2.2 Get arch of the dso_path, and decide the addr_step for it. addr_step is the step we
          change addr each time. For example, since instructions of arm64 are all 4 bytes long,
          addr_step for arm64 can be 4.
          2.3 Use addr2line to find line info for each addr in the dso_path.
          2.4 For each addr without line info, use addr2line to find line info for
              range(addr - addr_step, addr - addr_step * 4 - 1, -addr_step).
          2.5 For each addr without line info, use addr2line to find line info for
              range(addr - addr_step * 5, addr - addr_step * 128 - 1, -addr_step).
              (128 is a guess number. A nested switch statement in
               system/core/demangle/Demangler.cpp has >300 bytes without line info in arm64.)
    """
    class Dso(object):
        """ Info of a dynamic shared library.
            addrs: a map from address to Addr object in this dso.
        """

        def __init__(self, build_id: Optional[str]):
            self.build_id = build_id
            self.addrs: Dict[int, Addr2Nearestline.Addr] = {}
            # Saving file names for each addr takes a lot of memory. So we store file ids in Addr,
            # and provide data structures connecting file id and file name here.
            self.file_name_to_id: Dict[str, int] = {}
            self.file_id_to_name: List[str] = []
            self.func_name_to_id: Dict[str, int] = {}
            self.func_id_to_name: List[str] = []

        def get_file_id(self, file_path: str) -> int:
            file_id = self.file_name_to_id.get(file_path)
            if file_id is None:
                file_id = self.file_name_to_id[file_path] = len(self.file_id_to_name)
                self.file_id_to_name.append(file_path)
            return file_id

        def get_func_id(self, func_name: str) -> int:
            func_id = self.func_name_to_id.get(func_name)
            if func_id is None:
                func_id = self.func_name_to_id[func_name] = len(self.func_id_to_name)
                self.func_id_to_name.append(func_name)
            return func_id

    class Addr(object):
        """ Info of an addr request.
            func_addr: start_addr of the function containing addr.
            source_lines: a list of [file_id, line_number] for addr.
                          source_lines[:-1] are all for inlined functions.
        """

        def __init__(self, func_addr: int):
            self.func_addr = func_addr
            self.source_lines: Optional[List[int, int]] = None

    def __init__(
            self, ndk_path: Optional[str],
            binary_finder: BinaryFinder, with_function_name: bool):
        self.symbolizer_path = ToolFinder.find_tool_path('llvm-symbolizer', ndk_path)
        if not self.symbolizer_path:
            log_exit("Can't find llvm-symbolizer. " + NDK_ERROR_MESSAGE)
        self.readelf = ReadElf(ndk_path)
        self.dso_map: Dict[str, Addr2Nearestline.Dso] = {}  # map from dso_path to Dso.
        self.binary_finder = binary_finder
        self.with_function_name = with_function_name

    def add_addr(self, dso_path: str, build_id: Optional[str], func_addr: int, addr: int):
        dso = self.dso_map.get(dso_path)
        if dso is None:
            dso = self.dso_map[dso_path] = self.Dso(build_id)
        if addr not in dso.addrs:
            dso.addrs[addr] = self.Addr(func_addr)

    def convert_addrs_to_lines(self, jobs: int):
        with ThreadPoolExecutor(jobs) as executor:
            futures: List[Future] = []
            for dso_path, dso in self.dso_map.items():
                futures.append(executor.submit(self._convert_addrs_in_one_dso, dso_path, dso))
            for future in futures:
                # Call future.result() to report exceptions raised in the executor.
                future.result()

    def _convert_addrs_in_one_dso(self, dso_path: str, dso: Addr2Nearestline.Dso):
        real_path = self.binary_finder.find_binary(dso_path, dso.build_id)
        if not real_path:
            if dso_path not in ['//anon', 'unknown', '[kernel.kallsyms]']:
                logging.debug("Can't find dso %s" % dso_path)
            return

        if not self._check_debug_line_section(real_path):
            logging.debug("file %s doesn't contain .debug_line section." % real_path)
            return

        addr_step = self._get_addr_step(real_path)
        self._collect_line_info(dso, real_path, [0])
        self._collect_line_info(dso, real_path, range(-addr_step, -addr_step * 4 - 1, -addr_step))
        self._collect_line_info(dso, real_path,
                                range(-addr_step * 5, -addr_step * 128 - 1, -addr_step))

    def _check_debug_line_section(self, real_path: Path) -> bool:
        return '.debug_line' in self.readelf.get_sections(real_path)

    def _get_addr_step(self, real_path: Path) -> int:
        arch = self.readelf.get_arch(real_path)
        if arch == 'arm64':
            return 4
        if arch == 'arm':
            return 2
        return 1

    def _collect_line_info(
            self, dso: Addr2Nearestline.Dso, real_path: Path, addr_shifts: List[int]):
        """ Use addr2line to get line info in a dso, with given addr shifts. """
        # 1. Collect addrs to send to addr2line.
        addr_set: Set[int] = set()
        for addr in dso.addrs:
            addr_obj = dso.addrs[addr]
            if addr_obj.source_lines:  # already has source line, no need to search.
                continue
            for shift in addr_shifts:
                # The addr after shift shouldn't change to another function.
                shifted_addr = max(addr + shift, addr_obj.func_addr)
                addr_set.add(shifted_addr)
                if shifted_addr == addr_obj.func_addr:
                    break
        if not addr_set:
            return
        addr_request = '\n'.join(['0x%x' % addr for addr in sorted(addr_set)])

        # 2. Use addr2line to collect line info.
        try:
            subproc = subprocess.Popen(self._build_symbolizer_args(real_path),
                                       stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate(str_to_bytes(addr_request))
            stdoutdata = bytes_to_str(stdoutdata)
        except OSError:
            return
        addr_map = self.parse_line_output(stdoutdata, dso)

        # 3. Fill line info in dso.addrs.
        for addr in dso.addrs:
            addr_obj = dso.addrs[addr]
            if addr_obj.source_lines:
                continue
            for shift in addr_shifts:
                shifted_addr = max(addr + shift, addr_obj.func_addr)
                lines = addr_map.get(shifted_addr)
                if lines:
                    addr_obj.source_lines = lines
                    break
                if shifted_addr == addr_obj.func_addr:
                    break

    def _build_symbolizer_args(self, binary_path: Path) -> List[str]:
        args = [self.symbolizer_path, '--print-address', '--inlining', '--obj=%s' % binary_path]
        if self.with_function_name:
            args += ['--functions=linkage', '--demangle']
        else:
            args.append('--functions=none')
        return args

    def parse_line_output(self, output: str, dso: Addr2Nearestline.Dso) -> Dict[int,
                                                                                List[Tuple[int]]]:
        """
        The output is a list of lines.
            address1
            function_name1 (the function name can be empty)
            source_location1
            function_name2
            source_location2
            ...
            (end with empty line)
        """

        addr_map: Dict[int, List[Tuple[int]]] = {}
        lines = output.strip().splitlines()
        i = 0
        while i < len(lines):
            address = self._parse_line_output_address(lines[i])
            i += 1
            if address is None:
                continue
            info = []
            while i < len(lines):
                if self.with_function_name:
                    if i + 1 == len(lines):
                        break
                    function_name = lines[i].strip()
                    if not function_name and (':' not in lines[i+1]):
                        # no more frames
                        break
                    i += 1
                elif not lines[i]:
                    i += 1
                    break

                file_path, line_number = self._parse_line_output_source_location(lines[i])
                i += 1
                if not file_path or not line_number:
                    # An addr can have a list of (file, line), when the addr belongs to an inlined
                    # function. Sometimes only part of the list has ? mark. In this case, we think
                    # the line info is valid if the first line doesn't have ? mark.
                    if not info:
                        break
                    continue
                file_id = dso.get_file_id(file_path)
                if self.with_function_name:
                    func_id = dso.get_func_id(function_name)
                    info.append((file_id, line_number, func_id))
                else:
                    info.append((file_id, line_number))
            if info:
                addr_map[address] = info
        return addr_map

    def _parse_line_output_address(self, output: str) -> Optional[int]:
        if output.startswith('0x'):
            return int(output, 16)
        return None

    def _parse_line_output_source_location(self, line: str) -> Tuple[Optional[str], Optional[int]]:
        file_path, line_number = None, None
        # Handle lines in format filename:line:column, like "runtest/two_functions.cpp:14:25".
        # Filename may contain ':' like "C:\Users\...\file".
        items = line.rsplit(':', 2)
        if len(items) == 3:
            file_path, line_number = items[:2]
        if not file_path or ('?' in file_path) or not line_number or ('?' in line_number):
            return None, None
        try:
            line_number = int(line_number)
        except ValueError:
            return None, None
        return file_path, line_number

    def get_dso(self, dso_path: str) -> Addr2Nearestline.Dso:
        return self.dso_map.get(dso_path)

    def get_addr_source(self, dso: Addr2Nearestline.Dso, addr: int) -> Optional[List[Tuple[int]]]:
        source = dso.addrs[addr].source_lines
        if source is None:
            return None
        if self.with_function_name:
            return [(dso.file_id_to_name[file_id], line, dso.func_id_to_name[func_id])
                    for (file_id, line, func_id) in source]
        return [(dso.file_id_to_name[file_id], line) for (file_id, line) in source]


class SourceFileSearcher(object):
    """ Find source file paths in the file system.
        The file paths reported by addr2line are the paths stored in debug sections
        of shared libraries. And we need to convert them to file paths in the file
        system. It is done in below steps:
        1. Collect all file paths under the provided source_dirs. The suffix of a
           source file should contain one of below:
            h: for C/C++ header files.
            c: for C/C++ source files.
            java: for Java source files.
            kt: for Kotlin source files.
        2. Given an abstract_path reported by addr2line, select the best real path
           as below:
           2.1 Find all real paths with the same file name as the abstract path.
           2.2 Select the real path having the longest common suffix with the abstract path.
    """

    SOURCE_FILE_EXTS = {'.h', '.hh', '.H', '.hxx', '.hpp', '.h++',
                        '.c', '.cc', '.C', '.cxx', '.cpp', '.c++',
                        '.java', '.kt'}

    @classmethod
    def is_source_filename(cls, filename: str) -> bool:
        ext = os.path.splitext(filename)[1]
        return ext in cls.SOURCE_FILE_EXTS

    def __init__(self, source_dirs: List[str]):
        # Map from filename to a list of reversed directory path containing filename.
        self.filename_to_rparents: Dict[str, List[str]] = {}
        self._collect_paths(source_dirs)

    def _collect_paths(self, source_dirs: List[str]):
        for source_dir in source_dirs:
            for parent, _, file_names in os.walk(source_dir):
                rparent = None
                for file_name in file_names:
                    if self.is_source_filename(file_name):
                        rparents = self.filename_to_rparents.get(file_name)
                        if rparents is None:
                            rparents = self.filename_to_rparents[file_name] = []
                        if rparent is None:
                            rparent = parent[::-1]
                        rparents.append(rparent)

    def get_real_path(self, abstract_path: str) -> Optional[str]:
        abstract_path = abstract_path.replace('/', os.sep)
        abstract_parent, file_name = os.path.split(abstract_path)
        abstract_rparent = abstract_parent[::-1]
        real_rparents = self.filename_to_rparents.get(file_name)
        if real_rparents is None:
            return None
        best_matched_rparent = None
        best_common_length = -1
        for real_rparent in real_rparents:
            length = len(os.path.commonprefix((real_rparent, abstract_rparent)))
            if length > best_common_length:
                best_common_length = length
                best_matched_rparent = real_rparent
        if best_matched_rparent is None:
            return None
        return os.path.join(best_matched_rparent[::-1], file_name)


class AddrRange:
    def __init__(self, start: int, len: int):
        self.start = start
        self.len = len

    @property
    def end(self) -> int:
        return self.start + self.len

    def is_in_range(self, addr: int) -> bool:
        return addr >= self.start and addr < self.end


class Disassembly:
    def __init__(self):
        self.lines: List[Tuple[str, int]] = []


class Objdump(object):
    """ A wrapper of objdump to disassemble code. """

    def __init__(self, ndk_path: Optional[str], binary_finder: BinaryFinder):
        self.ndk_path = ndk_path
        self.binary_finder = binary_finder
        self.readelf = ReadElf(ndk_path)
        self.objdump_paths: Dict[str, str] = {}

    def get_dso_info(self, dso_path: str, expected_build_id: Optional[str]
                     ) -> Optional[Tuple[str, str]]:
        real_path = self.binary_finder.find_binary(dso_path, expected_build_id)
        if not real_path:
            return None
        arch = self.readelf.get_arch(real_path)
        if arch == 'unknown':
            return None
        return (str(real_path), arch)

    def disassemble_function(self, dso_info, addr_range: AddrRange) -> Optional[Disassembly]:
        """ Disassemble code for an addr range in a binary.
        """
        real_path, arch = dso_info
        objdump_path = self.objdump_paths.get(arch)
        if not objdump_path:
            objdump_path = ToolFinder.find_tool_path('llvm-objdump', self.ndk_path, arch)
            if not objdump_path:
                log_exit("Can't find llvm-objdump." + NDK_ERROR_MESSAGE)
            self.objdump_paths[arch] = objdump_path

        # Run objdump.
        args = [objdump_path, '-dlC', '--no-show-raw-insn',
                '--start-address=0x%x' % addr_range.start,
                '--stop-address=0x%x' % (addr_range.end),
                real_path]
        if arch == 'arm' and 'llvm-objdump' in objdump_path:
            args += ['--print-imm-hex']
        try:
            subproc = subprocess.Popen(args, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate()
            stdoutdata = bytes_to_str(stdoutdata)
        except OSError:
            return None

        if not stdoutdata:
            return None
        result = Disassembly()
        for line in stdoutdata.split('\n'):
            line = line.rstrip()  # Remove '\r' on Windows.
            items = line.split(':', 1)
            try:
                addr = int(items[0], 16)
            except ValueError:
                addr = 0
            result.lines.append((line, addr))
        return result

    def disassemble_functions(self, dso_info, sorted_addr_ranges: List[AddrRange]
                              ) -> Optional[List[Disassembly]]:
        """ Disassemble code for multiple addr ranges in a binary. sorted_addr_ranges should be
            sorted by addr_range.start.
        """
        real_path, arch = dso_info
        objdump_path = self.objdump_paths.get(arch)
        if not objdump_path:
            objdump_path = ToolFinder.find_tool_path('llvm-objdump', self.ndk_path, arch)
            if not objdump_path:
                log_exit("Can't find llvm-objdump." + NDK_ERROR_MESSAGE)
            self.objdump_paths[arch] = objdump_path

        # Run objdump.
        args = [objdump_path, '-dlC', '--no-show-raw-insn', real_path]
        if arch == 'arm' and 'llvm-objdump' in objdump_path:
            args += ['--print-imm-hex']
        current_id = 0
        in_range = False
        result = [Disassembly() for _ in sorted_addr_ranges]
        try:
            proc = subprocess.Popen(args, stdout=subprocess.PIPE, text=True)
            while True:
                line = proc.stdout.readline()
                if not line:
                    break
                if current_id >= len(sorted_addr_ranges):
                    continue
                if line[0] == ' ':
                    # may be an instruction, like: " 24a469c: stp x29, x30, [sp, #-0x60]!"
                    items = line.split(':', 1)
                    try:
                        addr = int(items[0], 16)
                    except (ValueError, IndexError):
                        addr = 0
                else:
                    # may be a function start point, like "00000000024a4698 <DoWork()>:"
                    items = line.split(maxsplit=1)
                    try:
                        addr = int(items[0], 16)
                    except (ValueError, IndexError):
                        addr = 0

                if addr != 0:
                    if in_range and not sorted_addr_ranges[current_id].is_in_range(addr):
                        in_range = False
                        current_id += 1
                        if current_id == len(sorted_addr_ranges):
                            continue
                    if not in_range and sorted_addr_ranges[current_id].is_in_range(addr):
                        in_range = True

                if in_range:
                    result[current_id].lines.append((line, addr))
            proc.wait()
        except OSError:
            return None
        return result


class ReadElf(object):
    """ A wrapper of readelf. """

    def __init__(self, ndk_path: Optional[str]):
        self.readelf_path = ToolFinder.find_tool_path('llvm-readelf', ndk_path)
        if not self.readelf_path:
            log_exit("Can't find llvm-readelf. " + NDK_ERROR_MESSAGE)

    @staticmethod
    def is_elf_file(path: Union[Path, str]) -> bool:
        if os.path.isfile(path):
            with open(path, 'rb') as fh:
                return fh.read(4) == b'\x7fELF'
        return False

    def get_arch(self, elf_file_path: Union[Path, str]) -> str:
        """ Get arch of an elf file. """
        if self.is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-h', str(elf_file_path)])
                output = bytes_to_str(output)
                if output.find('AArch64') != -1:
                    return 'arm64'
                if output.find('ARM') != -1:
                    return 'arm'
                if output.find('X86-64') != -1:
                    return 'x86_64'
                if output.find('80386') != -1:
                    return 'x86'
            except subprocess.CalledProcessError:
                pass
        return 'unknown'

    def get_build_id(self, elf_file_path: Union[Path, str], with_padding=True) -> str:
        """ Get build id of an elf file. """
        if self.is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-n', str(elf_file_path)])
                output = bytes_to_str(output)
                result = re.search(r'Build ID:\s*(\S+)', output)
                if result:
                    build_id = result.group(1)
                    if with_padding:
                        build_id = self.pad_build_id(build_id)
                    return build_id
            except subprocess.CalledProcessError:
                pass
        return ""

    @staticmethod
    def pad_build_id(build_id: str) -> str:
        """ Pad build id to 40 hex numbers (20 bytes). """
        if len(build_id) < 40:
            build_id += '0' * (40 - len(build_id))
        else:
            build_id = build_id[:40]
        return '0x' + build_id

    @staticmethod
    def unpad_build_id(build_id: str) -> str:
        if build_id.startswith('0x'):
            build_id = build_id[2:]
            # Unpad build id as TrimZeroesFromBuildIDString() in quipper.
            padding = '0' * 8
            while build_id.endswith(padding):
                build_id = build_id[:-len(padding)]
        return build_id

    def get_sections(self, elf_file_path: Union[Path, str]) -> List[str]:
        """ Get sections of an elf file. """
        section_names: List[str] = []
        if self.is_elf_file(elf_file_path):
            try:
                output = subprocess.check_output([self.readelf_path, '-SW', str(elf_file_path)])
                output = bytes_to_str(output)
                for line in output.split('\n'):
                    # Parse line like:" [ 1] .note.android.ident NOTE  0000000000400190 ...".
                    result = re.search(r'^\s+\[\s*\d+\]\s(.+?)\s', line)
                    if result:
                        section_name = result.group(1).strip()
                        if section_name:
                            section_names.append(section_name)
            except subprocess.CalledProcessError:
                pass
        return section_names


def extant_dir(arg: str) -> str:
    """ArgumentParser type that only accepts extant directories.

    Args:
        arg: The string argument given on the command line.
    Returns: The argument as a realpath.
    Raises:
        argparse.ArgumentTypeError: The given path isn't a directory.
    """
    path = os.path.realpath(arg)
    if not os.path.isdir(path):
        raise argparse.ArgumentTypeError('{} is not a directory.'.format(path))
    return path


def extant_file(arg: str) -> str:
    """ArgumentParser type that only accepts extant files.

    Args:
        arg: The string argument given on the command line.
    Returns: The argument as a realpath.
    Raises:
        argparse.ArgumentTypeError: The given path isn't a file.
    """
    path = os.path.realpath(arg)
    if not os.path.isfile(path):
        raise argparse.ArgumentTypeError('{} is not a file.'.format(path))
    return path


def log_fatal(msg: str):
    raise Exception(msg)


def log_exit(msg: str):
    sys.exit(msg)


class LogFormatter(logging.Formatter):
    """ Use custom logging format. """

    def __init__(self):
        super().__init__('%(asctime)s [%(levelname)s] (%(filename)s:%(lineno)d) %(message)s')

    def formatTime(self, record, datefmt):
        return super().formatTime(record, '%H:%M:%S') + ',%03d' % record.msecs


class Log:
    initialized = False

    @classmethod
    def init(cls, log_level: str = 'info'):
        assert not cls.initialized
        cls.initialized = True
        cls.logger = logging.root
        cls.logger.setLevel(log_level.upper())
        handler = logging.StreamHandler()
        handler.setFormatter(LogFormatter())
        cls.logger.addHandler(handler)


class ArgParseFormatter(
        argparse.ArgumentDefaultsHelpFormatter, argparse.RawDescriptionHelpFormatter):
    pass


@dataclass
class ReportLibOptions:
    show_art_frames: bool
    trace_offcpu: str
    proguard_mapping_files: List[str]
    sample_filters: List[str]
    aggregate_threads: List[str]


class BaseArgumentParser(argparse.ArgumentParser):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs, formatter_class=ArgParseFormatter)
        self.has_sample_filter_options = False
        self.sample_filter_with_pid_shortcut = False
        self.has_report_lib_options = False

    def add_report_lib_options(self, group: Optional[Any] = None,
                               default_show_art_frames: bool = False,
                               sample_filter_group: Optional[Any] = None,
                               sample_filter_with_pid_shortcut: bool = True):
        self.has_report_lib_options = True
        parser = group if group else self
        parser.add_argument(
            '--proguard-mapping-file', nargs='+',
            help='Add proguard mapping file to de-obfuscate symbols')
        parser.add_argument('--show-art-frames', '--show_art_frames',
                            action=argparse.BooleanOptionalAction, default=default_show_art_frames,
                            help='Show frames of internal methods in the ART Java interpreter.')
        parser.add_argument(
            '--trace-offcpu', choices=['on-cpu', 'off-cpu', 'on-off-cpu', 'mixed-on-off-cpu'],
            help="""Set report mode for profiles recorded with --trace-offcpu option. All possible
                    modes are: on-cpu (only on-cpu samples), off-cpu (only off-cpu samples),
                    on-off-cpu (both on-cpu and off-cpu samples, can be split by event name),
                    mixed-on-off-cpu (on-cpu and off-cpu samples using the same event name).
                    If not set, mixed-on-off-cpu mode is used.
                """)
        self._add_sample_filter_options(sample_filter_group, sample_filter_with_pid_shortcut)
        parser.add_argument(
            '--aggregate-threads', nargs='+', metavar='thread_name_regex',
            help="""Aggregate threads with names matching the same regex. As a result, samples from
                    different threads (like a thread pool) can be shown in one flamegraph.
                """)

    def _add_sample_filter_options(
            self, group: Optional[Any] = None, with_pid_shortcut: bool = True):
        if not group:
            group = self.add_argument_group('Sample filter options')
        group.add_argument('--exclude-pid', metavar='pid', nargs='+', type=int,
                           help='exclude samples for selected processes')
        group.add_argument('--exclude-tid', metavar='tid', nargs='+', type=int,
                           help='exclude samples for selected threads')
        group.add_argument(
            '--exclude-process-name', metavar='process_name_regex', nargs='+',
            help='exclude samples for processes with name containing the regular expression')
        group.add_argument(
            '--exclude-thread-name', metavar='thread_name_regex', nargs='+',
            help='exclude samples for threads with name containing the regular expression')

        if with_pid_shortcut:
            group.add_argument('--pid', metavar='pid', nargs='+', type=int,
                               help='only include samples for selected processes')
            group.add_argument('--tid', metavar='tid', nargs='+', type=int,
                               help='only include samples for selected threads')
        group.add_argument('--include-pid', metavar='pid', nargs='+', type=int,
                           help='only include samples for selected processes')
        group.add_argument('--include-tid', metavar='tid', nargs='+', type=int,
                           help='only include samples for selected threads')
        group.add_argument(
            '--include-process-name', metavar='process_name_regex', nargs='+',
            help='only include samples for processes with name containing the regular expression')
        group.add_argument(
            '--comm', '--include-thread-name', metavar='thread_name_regex',
            dest='include_thread_name', nargs='+',
            help='only include samples for threads with name containing the regular expression')
        group.add_argument(
            '--filter-file', metavar='file',
            help='use filter file to filter samples based on timestamps. ' +
            'The file format is in doc/sampler_filter.md.')
        self.has_sample_filter_options = True
        self.sample_filter_with_pid_shortcut = with_pid_shortcut

    def _build_sample_filter(self, args: argparse.Namespace) -> List[str]:
        """ Build sample filters, which can be passed to ReportLib.SetSampleFilter(). """
        filters = []
        if args.exclude_pid:
            filters.extend(['--exclude-pid', ','.join(str(pid) for pid in args.exclude_pid)])
        if args.exclude_tid:
            filters.extend(['--exclude-tid', ','.join(str(tid) for tid in args.exclude_tid)])
        if args.exclude_process_name:
            for name in args.exclude_process_name:
                filters.extend(['--exclude-process-name', name])
        if args.exclude_thread_name:
            for name in args.exclude_thread_name:
                filters.extend(['--exclude-thread-name', name])

        if args.include_pid:
            filters.extend(['--include-pid', ','.join(str(pid) for pid in args.include_pid)])
        if args.include_tid:
            filters.extend(['--include-tid', ','.join(str(tid) for tid in args.include_tid)])
        if self.sample_filter_with_pid_shortcut:
            if args.pid:
                filters.extend(['--include-pid', ','.join(str(pid) for pid in args.pid)])
            if args.tid:
                filters.extend(['--include-tid', ','.join(str(pid) for pid in args.tid)])
        if args.include_process_name:
            for name in args.include_process_name:
                filters.extend(['--include-process-name', name])
        if args.include_thread_name:
            for name in args.include_thread_name:
                filters.extend(['--include-thread-name', name])
        if args.filter_file:
            filters.extend(['--filter-file', args.filter_file])
        return filters

    def parse_known_args(self, *args, **kwargs):
        self.add_argument(
            '--log', choices=['debug', 'info', 'warning'],
            default='info', help='set log level')
        namespace, left_args = super().parse_known_args(*args, **kwargs)

        if self.has_report_lib_options:
            sample_filters = self._build_sample_filter(namespace)
            report_lib_options = ReportLibOptions(
                namespace.show_art_frames, namespace.trace_offcpu, namespace.proguard_mapping_file,
                sample_filters, namespace.aggregate_threads)
            setattr(namespace, 'report_lib_options', report_lib_options)

        if not Log.initialized:
            Log.init(namespace.log)
        return namespace, left_args
