#!/usr/bin/env python3
#
# Copyright (C) 2019 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.
#

"""
    This script is part of controlling simpleperf recording in user code. It is used to prepare
    profiling environment (upload simpleperf to device and enable profiling) before recording
    and collect recording data on host after recording.
    Controlling simpleperf recording is done in below steps:
    1. Add simpleperf Java API/C++ API to the app's source code. And call the API in user code.
    2. Run `api_profiler.py prepare` to prepare profiling environment.
    3. Run the app one or more times to generate recording data.
    4. Run `api_profiler.py collect` to collect recording data on host.
"""

import logging
import os
import os.path
import shutil
import zipfile

from simpleperf_utils import (AdbHelper, BaseArgumentParser,
                              get_target_binary_path, log_exit, remove)


def prepare_recording(args):
    adb = AdbHelper()
    enable_profiling_on_device(adb, args)
    upload_simpleperf_to_device(adb)
    run_simpleperf_prepare_cmd(adb)


def enable_profiling_on_device(adb, args):
    android_version = adb.get_android_version()
    if android_version >= 10:
        adb.set_property('debug.perf_event_max_sample_rate', str(args.max_sample_rate[0]))
        adb.set_property('debug.perf_cpu_time_max_percent', str(args.max_cpu_percent[0]))
        adb.set_property('debug.perf_event_mlock_kb', str(args.max_memory_in_kb[0]))
    adb.set_property('security.perf_harden', '0')


def upload_simpleperf_to_device(adb):
    device_arch = adb.get_device_arch()
    simpleperf_binary = get_target_binary_path(device_arch, 'simpleperf')
    adb.check_run(['push', simpleperf_binary, '/data/local/tmp'])
    adb.check_run(['shell', 'chmod', 'a+x', '/data/local/tmp/simpleperf'])


def run_simpleperf_prepare_cmd(adb):
    adb.check_run(['shell', '/data/local/tmp/simpleperf', 'api-prepare'])


def collect_data(args):
    adb = AdbHelper()
    if not os.path.isdir(args.out_dir):
        os.makedirs(args.out_dir)
    download_recording_data(adb, args)
    unzip_recording_data(args)


def download_recording_data(adb, args):
    """ download recording data to simpleperf_data.zip."""
    upload_simpleperf_to_device(adb)
    adb.check_run(['shell', '/data/local/tmp/simpleperf', 'api-collect', '--app', args.app[0],
                   '-o', '/data/local/tmp/simpleperf_data.zip'])
    adb.check_run(['pull', '/data/local/tmp/simpleperf_data.zip', args.out_dir])
    adb.check_run(['shell', 'rm', '-rf', '/data/local/tmp/simpleperf_data'])


def unzip_recording_data(args):
    zip_file_path = os.path.join(args.out_dir, 'simpleperf_data.zip')
    with zipfile.ZipFile(zip_file_path, 'r') as zip_fh:
        names = zip_fh.namelist()
        logging.info('There are %d recording data files.' % len(names))
        for name in names:
            logging.info('recording file: %s' % os.path.join(args.out_dir, name))
            zip_fh.extract(name, args.out_dir)
    remove(zip_file_path)


def main():
    parser = BaseArgumentParser(description=__doc__)
    subparsers = parser.add_subparsers()
    prepare_parser = subparsers.add_parser('prepare', help='Prepare recording on device.')
    prepare_parser.add_argument('--max-sample-rate', nargs=1, type=int, default=[100000], help="""
                                Set max sample rate (only on Android >= Q).""")
    prepare_parser.add_argument('--max-cpu-percent', nargs=1, type=int, default=[25], help="""
                                Set max cpu percent for recording (only on Android >= Q).""")
    prepare_parser.add_argument('--max-memory-in-kb', nargs=1, type=int,
                                default=[(1024 + 1) * 4 * 8], help="""
                                Set max kernel buffer size for recording (only on Android >= Q).
                                """)
    prepare_parser.set_defaults(func=prepare_recording)
    collect_parser = subparsers.add_parser('collect', help='Collect recording data.')
    collect_parser.add_argument('-p', '--app', nargs=1, required=True, help="""
                                The app package name of the app profiled.""")
    collect_parser.add_argument('-o', '--out-dir', default='simpleperf_data', help="""
                                The directory to store recording data.""")
    collect_parser.set_defaults(func=collect_data)
    args = parser.parse_args()
    args.func(args)


if __name__ == '__main__':
    main()
