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

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

SUPPORTED_MIME_TYPES = [
    'text/html',
    'text/sky',
    'text/plain',
]

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/skydb.pids"
CACHE_LINKS_PATH = '/tmp/mojo_cache_links'
SYSTEM_LIBS_ROOT_PATH = '/tmp/device_libs'

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


# 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


def ensure_assets_are_downloaded(build_dir):
    sky_pkg_dir = os.path.join(build_dir, 'gen', 'dart-pkg', 'sky')
    sky_pkg_lib_dir = os.path.join(sky_pkg_dir, 'lib')
    sky_icons_dir = \
        os.path.join(sky_pkg_lib_dir, 'assets', 'material-design-icons')
    if not os.path.isdir(sky_icons_dir):
        logging.info('NOTE: sky/assets/material-design-icons missing, '
                     'Running `download_material_design_icons` for you.')
        subprocess.check_call(
            [os.path.join(sky_pkg_lib_dir, 'download_material_design_icons')])

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:sky_debugger %d' % remote_command_port,
            'mojo:sky_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, configuration, 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

        ensure_assets_are_downloaded(args.build_dir)

        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 skydb 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 'skydb 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?
            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,
            'tools', '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 skydb 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()
