#!/usr/bin/env python
# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import os
import re
import shutil
import subprocess
import sys

"""Tool for starting a GDB client and server to debug a Flutter engine process on an Android device.

Usage:
  flutter_gdb server com.example.package_name
  flutter_gdb client com.example.package_name

The Android package must be marked as debuggable in its manifest.

The "client" command will copy system libraries from the device to the host
in order to provide debug symbols.  If this has already been done on a
previous run for a given device, then you can skip this step by passing
--no-pull-libs.
"""

ADB_LOCAL_PATH = 'third_party/android_tools/sdk/platform-tools/adb'

def _get_flutter_root():
    path = os.path.dirname(os.path.abspath(__file__))
    while os.path.basename(path) != 'src':
        path = os.path.dirname(path)
    return path


def _find_package_pid(adb_path, package):
    """Find the pid of the Flutter application process."""
    ps_output = subprocess.check_output([adb_path, 'shell', 'ps'])
    ps_match = re.search('^\S+\s+(\d+).*\s%s' % package, ps_output, re.MULTILINE)
    if not ps_match:
        print 'Unable to find pid for package %s on device' % package
        return None
    return int(ps_match.group(1))


class GdbClient(object):
    SYSTEM_LIBS_PATH = '/tmp/flutter_gdb_device_libs'

    def _gdb_local_path(self):
        GDB_LOCAL_PATH = ('third_party/android_tools/ndk/prebuilt/%s-x86_64/bin/gdb-orig')
        if sys.platform.startswith('darwin'):
            return GDB_LOCAL_PATH % 'darwin'
        else:
            return GDB_LOCAL_PATH % 'linux'

    def add_subparser(self, subparsers):
        parser = subparsers.add_parser('client',
            help='run a GDB client')
        parser.add_argument('package', type=str)
        parser.add_argument('--local-engine', type=str, default='android_debug_unopt')
        parser.add_argument('--gdb-port', type=int, default=8888)
        parser.add_argument('--no-pull-libs', action="store_false",
            default=True, dest="pull_libs",
            help="Do not copy system libraries from the device to the host")
        parser.add_argument('--sysroot', action="store_true", default=False,
            help='Create a sysroot tree suitable for debugging on Android N')
        parser.set_defaults(func=self.run)

    def _copy_system_libs(self, adb_path, package, sysroot):
        """Copy libraries used by the Flutter process from the device to the host."""
        package_pid = _find_package_pid(adb_path, package)
        if package_pid is None:
            return False

        # Find library files that are mapped into the process.
        proc_maps = subprocess.check_output(
            [adb_path, 'shell', 'run-as', package, 'cat', '/proc/%d/maps' % package_pid])
        proc_libs = re.findall('(/system/.*\.(?:so|oat))\s*$', proc_maps, re.MULTILINE)

        if sysroot:
            device_libs = set((lib, lib[1:]) for lib in proc_libs)
            device_libs.add(('/system/bin/linker', 'system/bin/linker'))
            device_libs.add(('/system/bin/app_process32', 'system/bin/app_process32'))
        else:
            device_libs = set((lib, os.path.basename(lib)) for lib in proc_libs)
            device_libs.add(('/system/bin/linker', 'linker'))

        shutil.rmtree(GdbClient.SYSTEM_LIBS_PATH)

        dev_null = open(os.devnull, 'w')
        for lib, local_path in sorted(device_libs):
            print 'Copying %s' % lib
            local_path = os.path.join(GdbClient.SYSTEM_LIBS_PATH, local_path)
            if not os.path.exists(os.path.dirname(local_path)):
                os.makedirs(os.path.dirname(local_path))
            subprocess.check_call([adb_path, 'pull', lib, local_path], stderr=dev_null)

        return True

    def run(self, args):
        flutter_root = _get_flutter_root()
        if args.adb is None:
            adb_path = os.path.join(flutter_root, ADB_LOCAL_PATH)
        else:
            adb_path = args.adb

        if args.pull_libs:
            if not self._copy_system_libs(adb_path, args.package, args.sysroot):
                return 1

        subprocess.check_call(
            [adb_path, 'forward', 'tcp:%d' % args.gdb_port, 'tcp:%d' % args.gdb_port])

        debug_out_path = os.path.join(flutter_root, 'out/%s' % args.local_engine)
        if not os.path.exists(os.path.join(debug_out_path, 'libflutter.so')):
            print 'Unable to find libflutter.so. Make sure you have completed a %s build' % args.local_engine
            return 1

        eval_commands = []
        if args.sysroot:
            eval_commands.append('set sysroot %s' % GdbClient.SYSTEM_LIBS_PATH)
        eval_commands.append('set solib-search-path %s:%s' %
                             (debug_out_path, GdbClient.SYSTEM_LIBS_PATH))
        eval_commands.append('target remote localhost:%d' % args.gdb_port)

        exec_command = [os.path.join(flutter_root, self._gdb_local_path())]
        for command in eval_commands:
            exec_command += ['--eval-command', command]

        os.execv(exec_command[0], exec_command)


class GdbServer(object):
    GDB_SERVER_LOCAL_PATH = 'third_party/android_tools/ndk/prebuilt/android-arm/gdbserver/gdbserver'
    GDB_SERVER_DEVICE_TMP_PATH = '/data/local/tmp/gdbserver'

    def add_subparser(self, subparsers):
        parser = subparsers.add_parser('server',
            help='run a GDB server on the device')
        parser.add_argument('package', type=str)
        parser.add_argument('--gdb-port', type=int, default=8888)
        parser.set_defaults(func=self.run)

    def run(self, args):
        flutter_root = _get_flutter_root()
        if args.adb is None:
            adb_path = os.path.join(flutter_root, ADB_LOCAL_PATH)
        else:
            adb_path = args.adb

        package_pid = _find_package_pid(adb_path, args.package)
        if package_pid is None:
            return 1

        # Copy gdbserver to the package's data directory.
        subprocess.check_call([adb_path, 'push',
                               os.path.join(flutter_root, GdbServer.GDB_SERVER_LOCAL_PATH),
                               GdbServer.GDB_SERVER_DEVICE_TMP_PATH])
        gdb_server_device_path = '/data/data/%s/gdbserver' % args.package
        subprocess.check_call([adb_path, 'shell', 'run-as', args.package, 'cp',
                               GdbServer.GDB_SERVER_DEVICE_TMP_PATH,
                               gdb_server_device_path])

        # Run gdbserver.
        try:
            subprocess.call([adb_path, 'shell', 'run-as', args.package,
                             gdb_server_device_path,
                             '--attach', ':%d' % args.gdb_port, str(package_pid)])
        except KeyboardInterrupt:
            pass


def main():
    parser = argparse.ArgumentParser(description='Flutter debugger tool')
    subparsers = parser.add_subparsers(help='sub-command help')
    parser.add_argument('--adb', type=str, help='path to ADB tool')

    commands = [
        GdbClient(),
        GdbServer(),
    ]
    for command in commands:
        command.add_subparser(subparsers)

    args = parser.parse_args()
    return args.func(args)


if __name__ == '__main__':
    sys.exit(main())
