#!/usr/bin/env python
#
# 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 print_function
import logging
import os
import os.path
import shutil
import subprocess
import sys
import time

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

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

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

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

def is_python3():
    return sys.version_info >= (3, 0)


def log_debug(msg):
    logging.debug(msg)


def log_info(msg):
    logging.info(msg)


def log_warning(msg):
    logging.warning(msg)


def log_fatal(msg):
    raise Exception(msg)

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

def disable_debug_log():
    logging.getLogger().setLevel(logging.WARN)

def str_to_bytes(str):
    if not is_python3():
        return str
    # 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.encode('utf-8')

def bytes_to_str(bytes):
    if not is_python3():
        return bytes
    return bytes.decode('utf-8')

def get_target_binary_path(arch, binary_name):
    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):
    dir = 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'
        dir = os.path.join(dir, 'windows')
    elif sys.platform == 'darwin': # OSX
        if binary_name.endswith('.so'):
            binary_name = binary_name[0:-3] + '.dylib'
        dir = os.path.join(dir, 'darwin')
    else:
        dir = os.path.join(dir, 'linux')
    dir = os.path.join(dir, 'x86_64' if sys.maxsize > 2 ** 32 else 'x86')
    binary_path = os.path.join(dir, 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, option='--help'):
    """ 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:
        return False

DEFAULT_NDK_PATH = {
    'darwin': 'Library/Android/sdk/ndk-bundle',
    'linux': 'Android/Sdk/ndk-bundle',
    'windows': 'AppData/Local/Android/sdk/ndk-bundle',
}

EXPECTED_TOOLS = {
    'adb': {
        'is_binutils': False,
        'test_option': 'version',
        'path_in_ndk': '../platform-tools/adb',
    },
    'readelf': {
        'is_binutils': True,
        'accept_tool_without_arch': True,
    },
    'addr2line': {
        'is_binutils': True,
        'accept_tool_without_arch': True
    },
    'objdump': {
        'is_binutils': True,
    },
}

def _get_binutils_path_in_ndk(toolname, arch, platform):
    if not arch:
        arch = 'arm64'
    if arch == 'arm64':
        name = 'aarch64-linux-android-' + toolname
        path = 'toolchains/aarch64-linux-android-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'arm':
        name = 'arm-linux-androideabi-' + toolname
        path = 'toolchains/arm-linux-androideabi-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'x86_64':
        name = 'x86_64-linux-android-' + toolname
        path = 'toolchains/x86_64-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    elif arch == 'x86':
        name = 'i686-linux-android-' + toolname
        path = 'toolchains/x86-4.9/prebuilt/%s-x86_64/bin/%s' % (platform, name)
    else:
        log_fatal('unexpected arch %s' % arch)
    return (name, path)

def find_tool_path(toolname, ndk_path=None, arch=None):
    if toolname not in EXPECTED_TOOLS:
        return None
    tool_info = EXPECTED_TOOLS[toolname]
    is_binutils = tool_info['is_binutils']
    test_option = tool_info.get('test_option', '--help')
    platform = get_platform()
    if is_binutils:
        toolname_with_arch, path_in_ndk = _get_binutils_path_in_ndk(toolname, arch, platform)
    else:
        toolname_with_arch = toolname
        path_in_ndk = tool_info['path_in_ndk']
    path_in_ndk = path_in_ndk.replace('/', os.sep)

    # 1. Find tool in the given ndk path.
    if ndk_path:
        path = os.path.join(ndk_path, path_in_ndk)
        if is_executable_available(path, test_option):
            return path

    # 2. Find tool in the ndk directory containing simpleperf scripts.
    path = os.path.join('..', path_in_ndk)
    if is_executable_available(path, test_option):
        return path

    # 3. Find tool in the default ndk installation path.
    home = os.environ.get('HOMEPATH') if is_windows() else os.environ.get('HOME')
    if home:
        default_ndk_path = os.path.join(home, DEFAULT_NDK_PATH[platform].replace('/', os.sep))
        path = os.path.join(default_ndk_path, path_in_ndk)
        if is_executable_available(path, test_option):
            return path

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

    # 5. 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=True):
        adb_path = find_tool_path('adb')
        if not adb_path:
            log_exit("Can't find adb in PATH environment.")
        self.adb_path = adb_path
        self.enable_switch_to_root = enable_switch_to_root


    def run(self, adb_args):
        return self.run_and_return_output(adb_args)[0]


    def run_and_return_output(self, adb_args, stdout_file=None, log_output=True):
        adb_args = [self.adb_path] + adb_args
        log_debug('run adb cmd: %s' % adb_args)
        if stdout_file:
            with open(stdout_file, 'wb') as stdout_fh:
                returncode = subprocess.call(adb_args, stdout=stdout_fh)
            stdoutdata = ''
        else:
            subproc = subprocess.Popen(adb_args, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate()
            returncode = subproc.returncode
        result = (returncode == 0)
        if stdoutdata and adb_args[1] != 'push' and adb_args[1] != 'pull':
            stdoutdata = bytes_to_str(stdoutdata)
            if log_output:
                log_debug(stdoutdata)
        log_debug('run adb cmd: %s  [result %s]' % (adb_args, result))
        return (result, stdoutdata)

    def check_run(self, adb_args):
        self.check_run_and_return_output(adb_args)


    def check_run_and_return_output(self, adb_args, stdout_file=None, log_output=True):
        result, stdoutdata = self.run_and_return_output(adb_args, stdout_file, log_output)
        if not result:
            log_exit('run "adb %s" failed' % adb_args)
        return stdoutdata


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


    def switch_to_root(self):
        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):
        result, stdoutdata = self.run_and_return_output(['shell', 'getprop', name])
        return stdoutdata if result else None

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


    def get_device_arch(self):
        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())


    def get_android_version(self):
        build_version = self.get_property('ro.build.version.release')
        android_version = 0
        if build_version:
            if not build_version[0].isdigit():
                c = build_version[0].upper()
                if c.isupper() and c >= 'L':
                    android_version = ord(c) - ord('L') + 5
            else:
                strs = build_version.split('.')
                if strs:
                    android_version = int(strs[0])
        return android_version


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


def remove(dir_or_file):
    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):
    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:
            pass
    import webbrowser
    try:
        # Try to open the report with Chrome
        browser_key = ''
        for key, _ in webbrowser._browsers.items():
            if 'chrome' in key:
                browser_key = key
        browser = webbrowser.get(browser_key)
        browser.open(report_path, new=0, autoraise=True)
    except:
        # webbrowser.get() doesn't work well on darwin/windows.
        webbrowser.open_new_tab(report_path)


def find_real_dso_path(dso_path_in_record_file, binary_cache_path):
    """ Given the path of a shared library in perf.data, find its real path in the file system. """
    if dso_path_in_record_file[0] != '/' or dso_path_in_record_file == '//anon':
        return None
    if binary_cache_path:
        tmp_path = os.path.join(binary_cache_path, dso_path_in_record_file[1:])
        if os.path.isfile(tmp_path):
            return tmp_path
    if os.path.isfile(dso_path_in_record_file):
        return dso_path_in_record_file
    return None

def get_arch_of_dso_path(readelf_path, dso_path):
    try:
        output = subprocess.check_output([readelf_path, '-h', dso_path])
        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'


class Addr2Nearestline(object):
    """ Use addr2line to convert (dso_path, func_addr, addr) to (source_file, line) pairs.
        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):
            self.addrs = {}

    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):
            self.func_addr = func_addr
            self.source_lines = None

    def __init__(self, ndk_path, binary_cache_path):
        self.addr2line_path = find_tool_path('addr2line', ndk_path)
        if not self.addr2line_path:
            log_exit("Can't find addr2line. Please set ndk path by --ndk-path option.")
        self.readelf_path = find_tool_path('readelf', ndk_path)
        if not self.readelf_path:
            log_exit("Can't find readelf. Please set ndk path by --ndk-path option.")
        self.dso_map = {}  # map from dso_path to Dso.
        self.binary_cache_path = binary_cache_path
        # 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 = {}
        self.file_id_to_name = []

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

    def convert_addrs_to_lines(self):
        for dso_path in self.dso_map:
            self._convert_addrs_in_one_dso(dso_path, self.dso_map[dso_path])

    def _convert_addrs_in_one_dso(self, dso_path, dso):
        real_path = find_real_dso_path(dso_path, self.binary_cache_path)
        if not real_path:
            if dso_path not in ['//anon', 'unknown', '[kernel.kallsyms]']:
                log_debug("Can't find dso %s" % dso_path)
            return

        if not self._check_debug_line_section(real_path):
            log_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):
        try:
            output = subprocess.check_output([self.readelf_path, '-S', real_path])
            return output.find('.debug_line') != -1
        except subprocess.CalledProcessError:
            return False

    def _get_addr_step(self, real_path):
        arch = get_arch_of_dso_path(self.readelf_path, real_path)
        if arch == 'arm64':
            return 4
        if arch == 'arm':
            return 2
        return 1

    def _collect_line_info(self, dso, real_path, addr_shifts):
        """ Use addr2line to get line info in a dso, with given addr shifts. """
        # 1. Collect addrs to send to addr2line.
        addr_set = 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(['%x' % addr for addr in sorted(addr_set)])

        # 2. Use addr2line to collect line info.
        try:
            subproc = subprocess.Popen([self.addr2line_path, '-ai', '-e', real_path],
                                       stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate(str_to_bytes(addr_request))
            stdoutdata = bytes_to_str(stdoutdata)
        except:
            return
        addr_map = {}
        cur_line_list = None
        for line in stdoutdata.strip().split('\n'):
            if line[:2] == '0x':
                # a new address
                cur_line_list = addr_map[int(line, 16)] = []
            else:
                # a file:line.
                if cur_line_list is None:
                    continue
                # Handle lines like "C:\Users\...\file:32".
                items = line.rsplit(':', 1)
                if len(items) != 2:
                    continue
                if '?' in line:
                    # if ? in line, it doesn't have a valid line info.
                    # 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 cur_line_list:
                        cur_line_list = None
                    continue
                (file_path, line_number) = items
                line_number = line_number.split()[0]  # Remove comments after line number
                try:
                    line_number = int(line_number)
                except ValueError:
                    continue
                file_id = self._get_file_id(file_path)
                cur_line_list.append((file_id, line_number))

        # 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 _get_file_id(self, file_path):
        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_dso(self, dso_path):
        return self.dso_map.get(dso_path)

    def get_addr_source(self, dso, addr):
        source = dso.addrs[addr].source_lines
        if source is None:
            return None
        return [(self.file_id_to_name[file_id], line) for (file_id, line) in source]


class Objdump(object):
    """ A wrapper of objdump to disassemble code. """
    def __init__(self, ndk_path, binary_cache_path):
        self.ndk_path = ndk_path
        self.binary_cache_path = binary_cache_path
        self.readelf_path = find_tool_path('readelf', ndk_path)
        if not self.readelf_path:
            log_exit("Can't find readelf. Please set ndk path by --ndk_path option.")
        self.objdump_paths = {}

    def disassemble_code(self, dso_path, start_addr, addr_len):
        """ Disassemble [start_addr, start_addr + addr_len] of dso_path.
            Return a list of pair (disassemble_code_line, addr).
        """
        # 1. Find real path.
        real_path = find_real_dso_path(dso_path, self.binary_cache_path)
        if real_path is None:
            return None

        # 2. Get path of objdump.
        arch = get_arch_of_dso_path(self.readelf_path, real_path)
        objdump_path = self.objdump_paths.get(arch)
        if not objdump_path:
            objdump_path = find_tool_path('objdump', self.ndk_path, arch)
            if not objdump_path:
                log_exit("Can't find objdump. Please set ndk path by --ndk_path option.")
            self.objdump_paths[arch] = objdump_path

        # 3. Run objdump.
        args = [objdump_path, '-dlC', '--no-show-raw-insn',
                '--start-address=0x%x' % start_addr,
                '--stop-address=0x%x' % (start_addr + addr_len),
                real_path]
        try:
            subproc = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
            (stdoutdata, _) = subproc.communicate()
            stdoutdata = bytes_to_str(stdoutdata)
        except:
            return None

        if not stdoutdata:
            return None
        result = []
        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.append((line, addr))
        return result


logging.getLogger().setLevel(logging.DEBUG)
