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

"""app_profiler.py: manage the process of profiling an android app.
    It downloads simpleperf on device, uses it to collect samples from
    user's app, and pulls perf.data and needed binaries on host.
"""

from __future__ import print_function
import argparse
import copy
import os
import os.path
import shutil
import subprocess
import sys
import time

from binary_cache_builder import BinaryCacheBuilder
from simpleperf_report_lib import *
from utils import *

class AppProfiler(object):
    """Used to manage the process of profiling an android app.

    There are three steps:
       1. Prepare profiling.
       2. Profile the app.
       3. Collect profiling data.
    """
    def __init__(self, config):
        # check config variables
        config_names = ['app_package_name', 'native_lib_dir', 'apk_file_path',
                        'recompile_app', 'restart_app', 'main_activity',
                        'record_options', 'perf_data_path', 'adb_path', 'readelf_path',
                        'binary_cache_dir']
        for name in config_names:
            if not config.has_key(name):
                log_fatal('config [%s] is missing' % name)
        native_lib_dir = config.get('native_lib_dir')
        if native_lib_dir and not os.path.isdir(native_lib_dir):
            log_fatal('[native_lib_dir] "%s" is not a dir' % native_lib_dir)
        apk_file_path = config.get('apk_file_path')
        if apk_file_path and not os.path.isfile(apk_file_path):
            log_fatal('[apk_file_path] "%s" is not a file' % apk_file_path)
        self.config = config
        self.adb = AdbHelper(self.config['adb_path'])
        self.is_root_device = False
        self.android_version = 0
        self.device_arch = None
        self.app_arch = None
        self.app_pid = None


    def profile(self):
        log_info('prepare profiling')
        self.prepare_profiling()
        log_info('start profiling')
        self.start_and_wait_profiling()
        log_info('collect profiling data')
        self.collect_profiling_data()
        log_info('profiling is finished.')


    def prepare_profiling(self):
        self._get_device_environment()
        self._enable_profiling()
        self._recompile_app()
        self._restart_app()
        self._get_app_environment()
        self._download_simpleperf()
        self._download_native_libs()


    def _get_device_environment(self):
        self.is_root_device = self.adb.switch_to_root()

        # Get android version.
        build_version = self.adb.get_property('ro.build.version.release')
        if build_version:
            if not build_version[0].isdigit():
                c = build_version[0].upper()
                if c < 'L':
                    self.android_version = 0
                else:
                    self.android_version = ord(c) - ord('L') + 5
            else:
                strs = build_version.split('.')
                if strs:
                    self.android_version = int(strs[0])

        # Get device architecture.
        output = self.adb.check_run_and_return_output(['shell', 'uname', '-m'])
        if output.find('aarch64') != -1:
            self.device_arch = 'aarch64'
        elif output.find('arm') != -1:
            self.device_arch = 'arm'
        elif output.find('x86_64') != -1:
            self.device_arch = 'x86_64'
        elif output.find('86') != -1:
            self.device_arch = 'x86'
        else:
            log_fatal('unsupported architecture: %s' % output.strip())


    def _enable_profiling(self):
        self.adb.set_property('security.perf_harden', '0')
        if self.is_root_device:
            # We can enable kernel symbols
            self.adb.run(['shell', 'echo', '0', '>/proc/sys/kernel/kptr_restrict'])


    def _recompile_app(self):
        if not self.config['recompile_app']:
            return
        if self.android_version == 0:
            log_warning("Can't fully compile an app on android version < L.")
        elif self.android_version == 5 or self.android_version == 6:
            if not self.is_root_device:
                log_warning("Can't fully compile an app on android version < N on non-root devices.")
            elif not self.config['apk_file_path']:
                log_warning("apk file is needed to reinstall the app on android version < N.")
            else:
                flag = '-g' if self.android_version == 6 else '--include-debug-symbols'
                self.adb.set_property('dalvik.vm.dex2oat-flags', flag)
                self.adb.check_run(['install', '-r', self.config['apk_file_path']])
        elif self.android_version >= 7:
            self.adb.set_property('debug.generate-debug-info', 'true')
            self.adb.check_run(['shell', 'cmd', 'package', 'compile', '-f', '-m', 'speed',
                                self.config['app_package_name']])
        else:
            log_fatal('unreachable')


    def _restart_app(self):
        if not self.config['restart_app']:
            return
        pid = self._find_app_process()
        if pid is not None:
            self.adb.run(['shell', 'run-as', self.config['app_package_name'],
                          'kill', '-9', str(pid)])
            time.sleep(1)
        activity = self.config['app_package_name'] + '/' + self.config['main_activity']
        result = self.adb.run(['shell', 'am', 'start', '-n', activity])
        if not result:
            log_fatal("Can't start activity %s" % activity)
        for i in range(10):
            pid = self._find_app_process()
            if pid is not None:
                return pid
            time.sleep(1)
            log_info('Wait for the app process for %d seconds' % (i + 1))
        log_fatal("Can't find the app process")


    def _find_app_process(self):
        result, output = self.adb.run_and_return_output(
                ['shell', 'run-as', self.config['app_package_name'], 'ps'])
        if not result:
            return None
        output = output.split('\n')
        for line in output:
            strs = line.split()
            if len(strs) > 2 and strs[-1].find(self.config['app_package_name']) != -1:
                return int(strs[1])
        return None


    def _get_app_environment(self):
        self.app_pid = self._find_app_process()
        if self.app_pid is None:
            log_fatal("can't find process for app [%s]" % self.config['app_package_name'])
        if self.device_arch in ['aarch64', 'x86_64']:
            output = self.adb.check_run_and_return_output(
                ['shell', 'run-as', self.config['app_package_name'],
                'cat', '/proc/%d/maps' % self.app_pid])
            if output.find('linker64') != -1:
                self.app_arch = self.device_arch
            else:
                self.app_arch = 'arm' if self.device_arch == 'aarch64' else 'x86'
        else:
            self.app_arch = self.device_arch
        log_info('app_arch: %s' % self.app_arch)


    def _download_simpleperf(self):
        simpleperf_binary = get_target_binary_path(self.app_arch, 'simpleperf')
        self.adb.check_run(['push', simpleperf_binary, '/data/local/tmp'])
        self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
                            'cp', '/data/local/tmp/simpleperf', '.'])
        self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
                            'chmod', 'a+x', 'simpleperf'])


    def _download_native_libs(self):
        if not self.config['native_lib_dir']:
            return
        filename_dict = dict()
        for root, _, files in os.walk(self.config['native_lib_dir']):
            for file in files:
                if not file.endswith('.so'):
                    continue
                path = os.path.join(root, file)
                old_path = filename_dict.get(file)
                log_info('app_arch = %s' % self.app_arch)
                if self._is_lib_better(path, old_path):
                    log_info('%s is better than %s' % (path, old_path))
                    filename_dict[file] = path
                else:
                    log_info('%s is worse than %s' % (path, old_path))
        maps = self.adb.check_run_and_return_output(['shell', 'run-as',
                  self.config['app_package_name'], 'cat', '/proc/%d/maps' % self.app_pid])
        searched_lib = dict()
        for item in maps.split():
            if item.endswith('.so') and searched_lib.get(item) is None:
                searched_lib[item] = True
                # Use '/' as path separator as item comes from android environment.
                filename = item[item.rfind('/') + 1:]
                dirname = item[1:item.rfind('/')]
                path = filename_dict.get(filename)
                if path is None:
                    continue
                self.adb.check_run(['push', path, '/data/local/tmp'])
                self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
                                    'mkdir', '-p', dirname])
                self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
                                    'cp', '/data/local/tmp/' + filename, dirname])


    def _is_lib_better(self, new_path, old_path):
        """ Return true if new_path is more likely to be used on device. """
        if old_path is None:
            return True
        if self.app_arch == 'arm':
            result1 = new_path.find('armeabi-v7a/') != -1
            result2 = old_path.find('armeabi-v7a') != -1
            if result1 != result2:
                return result1
        arch_dir = 'arm64' if self.app_arch == 'aarch64' else self.app_arch + '/'
        result1 = new_path.find(arch_dir) != -1
        result2 = old_path.find(arch_dir) != -1
        if result1 != result2:
            return result1
        result1 = new_path.find('obj/') != -1
        result2 = old_path.find('obj/') != -1
        if result1 != result2:
            return result1
        return False


    def start_and_wait_profiling(self):
        self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
            './simpleperf', 'record', self.config['record_options'], '-p',
            str(self.app_pid), '--symfs', '.'])


    def collect_profiling_data(self):
        self.adb.check_run(['shell', 'run-as', self.config['app_package_name'],
                            'chmod', 'a+rw', 'perf.data'])
        self.adb.check_run(['shell', 'cp',
            '/data/data/%s/perf.data' % self.config['app_package_name'], '/data/local/tmp'])
        self.adb.check_run(['pull', '/data/local/tmp/perf.data', self.config['perf_data_path']])
        config = copy.copy(self.config)
        config['symfs_dirs'] = []
        if self.config['native_lib_dir']:
            config['symfs_dirs'].append(self.config['native_lib_dir'])
        binary_cache_builder = BinaryCacheBuilder(config)
        binary_cache_builder.build_binary_cache()


if __name__ == '__main__':
    parser = argparse.ArgumentParser(
        description='Profile an android app. See configurations in app_profiler.config.')
    parser.add_argument('--config', default='app_profiler.config',
                        help='Set configuration file. Default is app_profiler.config.')
    args = parser.parse_args()
    config = load_config(args.config)
    profiler = AppProfiler(config)
    profiler.profile()