#!/usr/bin/env python
# Copyright 2014 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 os
import sys

# We should remove the skypy dependencies from this script.
sys.path.append(os.path.abspath(os.path.join(__file__, '../../../sky/tools')))

from skypy.skyserver import SkyServer
import argparse
import json
import logging
import pipes
import re
import requests
import signal
import skypy.paths
import StringIO
import subprocess
import time
import urlparse
import platform

SUPPORTED_MIME_TYPES = [
    'text/html',
    'text/sky',
    'application/dart',
]

DEFAULT_SKY_COMMAND_PORT = 7777
GDB_PORT = 8888
SKY_SERVER_PORT = 9999
DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky"

ANDROID_PACKAGE = "org.chromium.mojo.shell"
ANDROID_ACTIVITY = "%s/.MojoShellActivity" % ANDROID_PACKAGE
ANDROID_APK_NAME = 'MojoShell.apk'

PID_FILE_PATH = "/tmp/mojodb.pids"
CACHE_LINKS_PATH = '/tmp/mojo_cache_links'

SRC_ROOT = skypy.paths.Paths('ignored').src_root
ADB_PATH = os.path.join(SRC_ROOT,
    'third_party/android_tools/sdk/platform-tools/adb')

# TODO(iansf): Fix undefined behavior when you have more than one device attached.
SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs/%s' % (subprocess.check_output([ADB_PATH, 'get-serialno']).strip())


# FIXME: Move this into mopy.config
def gn_args_from_build_dir(build_dir):
    gn_cmd = [
        'gn', 'args',
        build_dir,
        '--list', '--short'
    ]
    config = {}
    for line in subprocess.check_output(gn_cmd).strip().split('\n'):
        # FIXME: This doesn't handle = in values.
        key, value = line.split(' = ')
        config[key] = value
    return config


class SkyDebugger(object):
    def __init__(self):
        self.pids = {}
        self.paths = None

    def _server_root_for_url(self, url_or_path):
        path = os.path.abspath(url_or_path)
        if os.path.commonprefix([path, SRC_ROOT]) == SRC_ROOT:
            server_root = SRC_ROOT
        else:
            server_root = os.path.dirname(path)
            logging.warn(
                '%s is outside of mojo root, using %s as server root' %
                (path, server_root))
        return server_root

    def _in_chromoting(self):
        return os.environ.get('CHROME_REMOTE_DESKTOP_SESSION', False)

    def _wrap_for_android(self, shell_args):
        # am shell --esa: (someone shoot me now)
        #  [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]]
        #  (to embed a comma into a string escape it using "\,")
        escaped_args = map(lambda arg: arg.replace(',', '\\,'), shell_args)
        return [
            ADB_PATH, 'shell',
            'am', 'start',
            '-W',
            '-S',
            '-a', 'android.intent.action.VIEW',
            '-n', ANDROID_ACTIVITY,
            # FIXME: This quoting is very error-prone.  Perhaps we should read
            # our args from a file instead?
            '--esa', 'parameters', ','.join(escaped_args),
        ]

    def _build_mojo_shell_command(self, args, is_android):
        content_handlers = ['%s,%s' % (mime_type, 'mojo:sky_viewer')
            for mime_type in SUPPORTED_MIME_TYPES]

        remote_command_port = self.pids.get('remote_sky_command_port', self.pids['sky_command_port'])
        remote_server_port = self.pids.get('remote_sky_server_port', self.pids['sky_server_port'])

        shell_args = [
            '--v=1',
            '--content-handlers=%s' % ','.join(content_handlers),
            '--url-mappings=mojo:window_manager=mojo:kiosk_wm',
            '--args-for=mojo:debugger %d --wm' % remote_command_port,
            'mojo:debugger',
        ]

        if args.url_or_path:
            shell_args.append(
                '--args-for=mojo:window_manager %s' % self._url_from_args(args))

        if args.trace_startup:
            shell_args.append('--trace-startup')

        # Map all mojo: urls to http: urls using the --origin command.
        build_dir_url = SkyServer.url_for_path(
            remote_server_port,
            self.pids['sky_server_root'],
            self.pids['build_dir'])

        # TODO(eseidel): We should do this on linux, but we need to fix
        # mojo http loading to be faster first.
        if is_android:
            shell_args += ['--origin=%s' % build_dir_url]

        # Desktop-only work-around for mojo crashing under chromoting.
        if not is_android and args.use_osmesa:
            shell_args.append(
                '--args-for=mojo:native_viewport_service --use-osmesa')

        if is_android and args.gdb:
            shell_args.append('--wait-for-debugger')
            shell_args.append('--predictable-app-filenames')

        if 'remote_sky_server_port' in self.pids:
            shell_command = self._wrap_for_android(shell_args)
        else:
            shell_command = [self.paths.mojo_shell_path] + shell_args

        return shell_command

    def sky_server_for_args(self, args, packages_root):
        # FIXME: This is a hack.  sky_server should just take a build_dir
        # not a magical "configuration" name.
        configuration = os.path.basename(os.path.normpath(self.paths.build_dir))
        server_root = self._server_root_for_url(args.url_or_path)
        return SkyServer(SKY_SERVER_PORT, server_root, packages_root)

    def _create_paths_for_build_dir(self, build_dir):
        # skypy.paths.Paths takes a root-relative build_dir argument. :(
        abs_build_dir = os.path.abspath(build_dir)
        root_relative_build_dir = os.path.relpath(abs_build_dir, SRC_ROOT)
        return skypy.paths.Paths(root_relative_build_dir)

    def _find_remote_pid_for_package(self, package):
        ps_output = subprocess.check_output([ADB_PATH, 'shell', 'ps'])
        for line in ps_output.split('\n'):
            fields = line.split()
            if fields and fields[-1] == package:
                return fields[1]
        return None

    def _find_install_location_for_package(self, package):
        pm_command = [ADB_PATH, 'shell', 'pm', 'path', package]
        pm_output = subprocess.check_output(pm_command)
        # e.g. package:/data/app/org.chromium.mojo.shell-1/base.apk
        return pm_output.split(':')[-1]

    def start_command(self, args):
        # FIXME: Lame that we use self for a command-specific variable.
        self.paths = self._create_paths_for_build_dir(args.build_dir)
        self.stop_command(None) # Quit any existing process.

        # FIXME: This is probably not the right way to compute is_android
        # from the build directory?
        gn_args = gn_args_from_build_dir(self.paths.build_dir)
        is_android = 'android_sdk_version' in gn_args

        shell_found = True
        if is_android:
            apk_path = os.path.join(self.paths.build_dir, 'apks', ANDROID_APK_NAME)
            if not os.path.exists(apk_path):
                print "%s not found in build_dir '%s'" % \
                    (ANDROID_APK_NAME, os.path.join(args.build_dir, 'apks'))
                shell_found = False
        elif not os.path.exists(self.paths.mojo_shell_path):
            print "mojo_shell not found in build_dir '%s'" % args.build_dir
            shell_found = False

        if not shell_found:
            print "Are you sure you sure that's a valid build_dir location?"
            print "See mojodb start --help for more info"
            sys.exit(2)

        if is_android and args.gdb and not 'is_debug' in gn_args:
            # FIXME: We don't include gdbserver in the release APK...
            print "Cannot debug Release builds on Android"
            sys.exit(2)

        dart_pkg_dir = os.path.join(self.paths.build_dir, 'gen', 'dart-pkg')
        packages_root = os.path.join(dart_pkg_dir, 'packages')

        sky_server = self.sky_server_for_args(args, packages_root)
        self.pids['sky_server_pid'] = sky_server.start()
        self.pids['sky_server_port'] = sky_server.port
        self.pids['sky_server_root'] = sky_server.root

        self.pids['build_dir'] = self.paths.build_dir
        self.pids['sky_command_port'] = args.command_port

        if is_android:
            # TODO(eseidel): This should move into a helper method and handle
            # failures with nice messages explaining how to get root.
            subprocess.check_call([ADB_PATH, 'root'])

            # We could make installing conditional on an argument.
            # -r to replace an existing apk, -d to allow version downgrade.
            subprocess.check_call([ADB_PATH, 'install', '-r', '-d', apk_path])

            port_string = 'tcp:%s' % sky_server.port
            subprocess.check_call([
                ADB_PATH, 'reverse', port_string, port_string
            ])
            self.pids['remote_sky_server_port'] = sky_server.port

            port_string = 'tcp:%s' % args.command_port
            subprocess.check_call([
                ADB_PATH, 'forward', port_string, port_string
            ])
            self.pids['remote_sky_command_port'] = args.command_port

        shell_command = self._build_mojo_shell_command(args, is_android)

        # On android we can't launch inside gdb, but rather have to attach.
        if not is_android and args.gdb:
            shell_command = ['gdbserver', ':%d' % GDB_PORT] + shell_command

        print ' '.join(map(pipes.quote, shell_command))
        # This pid is meaningless on android (it's the adb shell pid)
        start_command_pid = subprocess.Popen(shell_command).pid

        if is_android:
            # TODO(eseidel): am start -W does not seem to work?
            pid_tries = 0
            while True:
                pid = self._find_remote_pid_for_package(ANDROID_PACKAGE)
                if pid or pid_tries > 3:
                    break
                logging.debug('No pid for %s yet, waiting' % ANDROID_PACKAGE)
                time.sleep(5)
                pid_tries += 1

            if not pid:
                logging.error('Failed to find mojo_shell pid on device!')
                return
            self.pids['mojo_shell_pid'] = pid
        else:
            self.pids['mojo_shell_pid'] = start_command_pid

        if args.gdb and is_android:
            # We push our own copy of gdbserver with the package since
            # the default gdbserver is a different version from our gdb.
            package_path = \
                self._find_install_location_for_package(ANDROID_PACKAGE)
            gdb_server_path = os.path.join(
                os.path.dirname(package_path), 'lib/arm/gdbserver')
            gdbserver_cmd = [
                ADB_PATH, 'shell',
                gdb_server_path, '--attach',
                ':%d' % GDB_PORT,
                str(self.pids['mojo_shell_pid'])
            ]
            print ' '.join(map(pipes.quote, gdbserver_cmd))
            self.pids['adb_shell_gdbserver_pid'] = \
                subprocess.Popen(gdbserver_cmd).pid

            port_string = 'tcp:%d' % GDB_PORT
            subprocess.check_call([
                ADB_PATH, 'forward', port_string, port_string
            ])
            self.pids['remote_gdbserver_port'] = GDB_PORT

        if not args.gdb:
            if not self._wait_for_sky_command_port():
                logging.error('Failed to start sky')
                self.stop_command(None)
        else:
            # We could just run gdb_attach_command here, but when I do that
            # it auto-suspends in my zsh.  Unclear why.
            # self.gdb_attach_command(args)
            print "Run 'mojodb gdb_attach' to attach."

    def _kill_if_exists(self, key, name):
        pid = self.pids.pop(key, None)
        if not pid:
            logging.info('No pid for %s, nothing to do.' % name)
            return
        logging.info('Killing %s (%d).' % (name, pid))
        try:
            os.kill(pid, signal.SIGTERM)
        except OSError:
            logging.info('%s (%d) already gone.' % (name, pid))

    def stop_command(self, args):
        # TODO(eseidel): mojo_shell crashes when attempting graceful shutdown.
        # self._run_basic_command('/quit')

        self._kill_if_exists('sky_server_pid', 'sky_server')

        if 'remote_sky_server_port' in self.pids:
            port_string = 'tcp:%s' % self.pids['remote_sky_server_port']
            subprocess.call([ADB_PATH, 'reverse', '--remove', port_string])

        if 'remote_sky_command_port' in self.pids:
            # adb forward --remove takes the *host* port, not the remote port.
            port_string = 'tcp:%s' % self.pids['sky_command_port']
            subprocess.call([ADB_PATH, 'forward', '--remove', port_string])

            subprocess.call([
                ADB_PATH, 'shell', 'am', 'force-stop', ANDROID_PACKAGE])
        else:
            # Only try to kill mojo_shell if it's running locally.
            self._kill_if_exists('mojo_shell_pid', 'mojo_shell')

        if 'remote_gdbserver_port' in self.pids:
            self._kill_if_exists('adb_shell_gdbserver_pid',
                'adb shell gdbserver')

            port_string = 'tcp:%s' % self.pids['remote_gdbserver_port']
            subprocess.call([ADB_PATH, 'forward', '--remove', port_string])
        self.pids = {} # Clear out our pid file.

    def _url_from_args(self, args):
        if urlparse.urlparse(args.url_or_path).scheme:
            return args.url_or_path
        # The load happens on the remote device, use the remote port.
        remote_sky_server_port = self.pids.get('remote_sky_server_port',
            self.pids['sky_server_port'])
        return SkyServer.url_for_path(remote_sky_server_port,
            self.pids['sky_server_root'], args.url_or_path)

    def load_command(self, args):
        self._run_basic_command('/load', self._url_from_args(args))

    def _read_mojo_map(self):
        # TODO(eseidel): Does not work for android.
        mojo_map_path = "/tmp/mojo_shell.%d.maps" % self.pids['mojo_shell_pid']
        with open(mojo_map_path, 'r') as maps_file:
            lines = maps_file.read().strip().split('\n')
            return dict(map(lambda line: line.split(' '), lines))

    def stop_tracing_command(self, args):
        file_name = args.file_name
        trace = self._send_command_to_sky('/stop_tracing').content
        with open(file_name, "wb") as trace_file:
            trace_file.write('{"traceEvents":[')
            trace_file.write(trace)
            trace_file.write(']}')
        print "Trace saved in %s" % file_name

    def stop_profiling_command(self, args):
        self._run_basic_command('/stop_profiling')
        mojo_map = self._read_mojo_map()

        # TODO(eseidel): We should have a helper for resolving urls, etc.
        remote_server_port = self.pids.get('remote_sky_server_port', self.pids['sky_server_port'])
        build_dir_url = SkyServer.url_for_path(
            remote_server_port,
            self.pids['sky_server_root'],
            self.pids['build_dir'])

        # Map /tmp cache paths to urls and then to local build_dir paths.
        def map_to_local_paths(match):
            path = match.group('mojo_path')
            url = mojo_map.get(path)
            if url and url.startswith(build_dir_url):
                return url.replace(build_dir_url, self.pids['build_dir'])
            return match.group(0)

        MOJO_PATH_RE = re.compile(r'(?P<mojo_path>\S+\.mojo)')
        MOJO_NAME_RE = re.compile(r'(?P<mojo_name>\w+)\.mojo')

        with open("sky_viewer.pprof", "rb+") as profile_file:
            # ISO-8859-1 can represent arbitrary binary while still keeping
            # ASCII characters in the ASCII range (allowing us to regexp).
            # http://en.wikipedia.org/wiki/ISO/IEC_8859-1
            as_string = profile_file.read().decode('iso-8859-1')
            # Using the mojo_shell.PID.maps file tmp paths to build_dir paths.
            as_string = MOJO_PATH_RE.sub(map_to_local_paths, as_string)
            # In release foo.mojo is stripped but libfoo_library.so isn't.
            as_string = MOJO_NAME_RE.sub(r'lib\1_library.so', as_string)
            profile_file.seek(0)
            profile_file.write(as_string.encode('iso-8859-1'))
            profile_file.truncate()

    def _command_base_url(self):
        return 'http://localhost:%s' % self.pids['sky_command_port']

    def _send_command_to_sky(self, command_path, payload=None):
        url = 'http://localhost:%s%s' % (
            self.pids['sky_command_port'], command_path)
        if payload:
            response = requests.post(url, payload)
        else:
            response = requests.get(url)
        return response

    def _run_basic_command(self, command_path, payload=None):
        print self._send_command_to_sky(command_path, payload=payload).text

    # FIXME: These could be made into a context object with __enter__/__exit__.
    def _load_pid_file(self, path):
        try:
            with open(path, 'r') as pid_file:
                return json.load(pid_file)
        except:
            if os.path.exists(path):
                logging.warn('Failed to read pid file: %s' % path)
            return {}

    def _write_pid_file(self, path, pids):
        try:
            with open(path, 'w') as pid_file:
                json.dump(pids, pid_file, indent=2, sort_keys=True)
        except:
            logging.warn('Failed to write pid file: %s' % path)

    def _add_basic_command(self, subparsers, name, url_path, help_text):
        parser = subparsers.add_parser(name, help=help_text)
        command = lambda args: self._run_basic_command(url_path)
        parser.set_defaults(func=command)

    def _wait_for_sky_command_port(self):
        tries = 0
        while True:
            try:
                self._run_basic_command('/')
                return True
            except:
                tries += 1
                if tries == 3:
                    logging.warn('Still waiting for sky on port %s' %
                        self.pids['sky_command_port'])
                if tries > 10:
                    return False
                time.sleep(1)

    def logcat_command(self, args):
        TAGS = [
            'AndroidHandler',
            'MojoMain',
            'MojoShellActivity',
            'MojoShellApplication',
            'chromium',
        ]
        subprocess.call([ADB_PATH, 'logcat', '-d', '-s'] + TAGS)

    def _pull_system_libraries(self, system_libs_root):
        # Pull down the system libraries this pid has already mapped in.
        # TODO(eseidel): This does not handle dynamic loads.
        library_cacher_path = os.path.join(
            self.paths.sky_tools_directory, 'android_library_cacher.py')
        subprocess.call([
            library_cacher_path, system_libs_root, self.pids['mojo_shell_pid']
        ])

        # TODO(eseidel): adb_gdb does, this, unclear why solib-absolute-prefix
        # doesn't make this explicit listing not necessary?
        return subprocess.check_output([
            'find', system_libs_root,
            '-mindepth', '1',
            '-maxdepth', '4',
            '-type', 'd',
        ]).strip().split('\n')

    def _add_android_library_links(self, links_path):
        # TODO(eseidel): This might not match mojo_shell on the device?
        # TODO(eseidel): Should we pass libmojo_shell.so as 'file' to gdb?
        shell_link_path = os.path.join(links_path, 'libmojo_shell.so')
        if os.path.lexists(shell_link_path):
            os.unlink(shell_link_path)
        os.symlink(self.paths.mojo_shell_path, shell_link_path)

    def gdb_attach_command(self, args):
        self.paths = self._create_paths_for_build_dir(self.pids['build_dir'])

        if not os.path.exists(CACHE_LINKS_PATH):
            os.makedirs(CACHE_LINKS_PATH)
        cache_linker_path = os.path.join(
             self.paths.sky_tools_directory, 'mojo_cache_linker.py')
        subprocess.check_call([
            cache_linker_path, CACHE_LINKS_PATH, self.paths.build_dir])

        symbol_search_paths = [
            self.pids['build_dir'],
            CACHE_LINKS_PATH,
        ]
        gdb_path = '/usr/bin/gdb'

        eval_commands = [
            'directory %s' % self.paths.src_root,
            'file %s' % self.paths.mojo_shell_path,
            'target remote localhost:%s' % GDB_PORT,
        ]

        # A bunch of extra work is needed for android:
        if 'remote_sky_server_port' in self.pids:
            self._add_android_library_links(CACHE_LINKS_PATH)

            system_lib_dirs = self._pull_system_libraries(SYSTEM_LIBS_ROOT_PATH)
            eval_commands.append(
                'set solib-absolute-prefix %s' % SYSTEM_LIBS_ROOT_PATH)

            symbol_search_paths = system_lib_dirs + symbol_search_paths

            # TODO(eseidel): We need to look up the toolchain somehow?
            if platform.system() == 'Darwin':
                gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/'
                    'toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/'
                    'bin/arm-linux-androideabi-gdb')
            else:
                gdb_path = os.path.join(SRC_ROOT, 'third_party/android_tools/ndk/'
                    'toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/'
                    'bin/arm-linux-androideabi-gdb')

        # Set solib-search-path after letting android modify symbol_search_paths
        eval_commands.append(
            'set solib-search-path %s' % ':'.join(symbol_search_paths))

        exec_command = [gdb_path]
        for command in eval_commands:
            exec_command += ['--eval-command', command]

        print " ".join(exec_command)

        # Write out our pid file before we exec ourselves.
        self._write_pid_file(PID_FILE_PATH, self.pids)

        # Exec gdb directly to avoid python intercepting symbols, etc.
        os.execv(exec_command[0], exec_command)

    def print_crash_command(self, args):
        logcat_cmd = [ADB_PATH, 'logcat', '-d']
        logcat = subprocess.Popen(logcat_cmd, stdout=subprocess.PIPE)

        stack_path = os.path.join(SRC_ROOT,
            'mojo', 'devtools', 'common', 'android_stack_parser', 'stack')
        stack = subprocess.Popen([stack_path, '-'], stdin=logcat.stdout)
        logcat.wait()
        stack.wait()

    def pids_command(self, args):
        print json.dumps(self.pids, indent=1)

    def main(self):
        logging.basicConfig(level=logging.WARNING)
        logging.getLogger("requests").setLevel(logging.WARNING)

        self.pids = self._load_pid_file(PID_FILE_PATH)

        parser = argparse.ArgumentParser(description='Sky launcher/debugger')
        subparsers = parser.add_subparsers(help='sub-command help')

        start_parser = subparsers.add_parser('start',
            help='launch a new mojo_shell with sky')
        start_parser.add_argument('--gdb', action='store_true')
        start_parser.add_argument('--command-port', type=int,
            default=DEFAULT_SKY_COMMAND_PORT)
        start_parser.add_argument('--use-osmesa', action='store_true',
            default=self._in_chromoting())
        start_parser.add_argument('build_dir', type=str)
        start_parser.add_argument('url_or_path', nargs='?', type=str,
            default=DEFAULT_URL)
        start_parser.add_argument('--show-command', action='store_true',
            help='Display the shell command and exit')
        start_parser.add_argument('--trace-startup', action='store_true')
        start_parser.set_defaults(func=self.start_command)

        stop_parser = subparsers.add_parser('stop',
            help=('stop sky (as listed in %s)' % PID_FILE_PATH))
        stop_parser.set_defaults(func=self.stop_command)

        pids_parser = subparsers.add_parser('pids',
            help='dump the current mojodb pids file')
        pids_parser.set_defaults(func=self.pids_command)

        logcat_parser = subparsers.add_parser('logcat',
            help=('dump sky-related logs from device'))
        logcat_parser.set_defaults(func=self.logcat_command)

        print_crash_parser = subparsers.add_parser('print_crash',
            help=('dump (and symbolicate) recent crash-stacks'))
        print_crash_parser.set_defaults(func=self.print_crash_command)

        gdb_attach_parser = subparsers.add_parser('gdb_attach',
            help='launch gdb and attach to gdbserver launched from start --gdb')
        gdb_attach_parser.set_defaults(func=self.gdb_attach_command)

        self._add_basic_command(subparsers, 'start_tracing', '/start_tracing',
            'starts tracing the running sky instance')
        self._add_basic_command(subparsers, 'reload', '/reload',
            'reload the current page')
        self._add_basic_command(subparsers, 'start_profiling', '/start_profiling',
            'starts profiling the running sky instance (Linux only)')

        stop_tracing_parser = subparsers.add_parser('stop_tracing',
            help='stops tracing the running sky instance')
        stop_tracing_parser.add_argument('file_name', type=str, default='sky_viewer.trace')
        stop_tracing_parser.set_defaults(func=self.stop_tracing_command)

        stop_profiling_parser = subparsers.add_parser('stop_profiling',
            help='stops profiling the running sky instance (Linux only)')
        stop_profiling_parser.set_defaults(func=self.stop_profiling_command)

        load_parser = subparsers.add_parser('load',
            help='load a new page in the currently running sky')
        load_parser.add_argument('url_or_path', type=str)
        load_parser.set_defaults(func=self.load_command)

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

        self._write_pid_file(PID_FILE_PATH, self.pids)


if __name__ == '__main__':
    SkyDebugger().main()
