#!/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 skypy.paths
from skypy.skyserver import SkyServer
import argparse
import json
import logging
import os
import pipes
import requests
import signal
import subprocess
import sys
import time
import urlparse

SRC_ROOT = skypy.paths.Paths('ignored').src_root
sys.path.insert(0, os.path.join(SRC_ROOT, 'build', 'android'))
from pylib import android_commands
from pylib import constants
from pylib import forwarder


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

DEFAULT_SKY_COMMAND_PORT = 7777
SKY_SERVER_PORT = 9999
PID_FILE_PATH = "/tmp/skydb.pids"
DEFAULT_URL = "https://raw.githubusercontent.com/domokit/mojo/master/sky/examples/home.sky"


# 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):
        build_dir_url = SkyServer.url_for_path(
            self.pids['remote_sky_server_port'],
            self.pids['sky_server_root'],
            self.pids['build_dir'])
        shell_args += ['--origin=%s' % build_dir_url]

        # 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', 'shell',
            'am', 'start',
            '-W',
            '-S',
            '-a', 'android.intent.action.VIEW',
            '-n', 'org.chromium.mojo.shell/.MojoShellActivity',
            # 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):
        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'])

        shell_args = [
            '--v=1',
            '--content-handlers=%s' % ','.join(content_handlers),
            '--url-mappings=mojo:window_manager=mojo:sky_debugger',
            '--args-for=mojo:sky_debugger_prompt %d' % remote_command_port,
            'mojo:window_manager',
        ]
        # FIXME: This probably is wrong for android?
        if args.use_osmesa:
            shell_args.append('--args-for=mojo:native_viewport_service --use-osmesa')

        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 _connect_to_device(self):
        device = android_commands.AndroidCommands(
            android_commands.GetAttachedDevices()[0])
        device.EnableAdbRoot()
        return device

    def sky_server_for_args(self, args):
        # 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(args.build_dir))
        server_root = self._server_root_for_url(args.url_or_path)
        sky_server = SkyServer(self.paths, SKY_SERVER_PORT,
            configuration, server_root)
        return sky_server

    def start_command(self, args):
        # skypy.paths.Paths takes a root-relative build_dir argument. :(
        build_dir = os.path.abspath(args.build_dir)
        root_relative_build_dir = os.path.relpath(build_dir, SRC_ROOT)
        # FIXME: Lame that we use self for a command-specific variable.
        self.paths = skypy.paths.Paths(root_relative_build_dir)

        self.stop_command(None) # Quit any existing process.
        self.pids = {} # Clear out our pid file.

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

        sky_server = self.sky_server_for_args(args)
        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'] = args.build_dir
        self.pids['sky_command_port'] = args.command_port

        if is_android:
            # Pray to the build/android gods in their misspelled tongue.
            constants.SetOutputDirectort(args.build_dir)

            device = self._connect_to_device()
            self.pids['device_serial'] = device.GetDevice()

            forwarder.Forwarder.Map([(0, sky_server.port)], device)
            device_http_port = forwarder.Forwarder.DevicePortForHostPort(
                sky_server.port)
            self.pids['remote_sky_server_port'] = device_http_port

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

        shell_command = self._build_mojo_shell_command(args)
        print ' '.join(map(pipes.quote, shell_command))
        self.pids['mojo_shell_pid'] = subprocess.Popen(shell_command).pid

        if args.gdb:
            print "Sorry, I'm not sure how best to wire up --gdb to work"
            print "with mojo_shell as a background process.  For now use:"
            print "gdb --pid %s" % self.pids['mojo_shell_pid']
            shell_command = ['gdb'] + shell_command

        if not self._wait_for_sky_command_port():
            logging.error('Failed to start sky')
            self.stop_command(None)
        else:
            self.load_command(args)

    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 (%s).' % (name, pid))
        try:
            os.kill(pid, signal.SIGTERM)
        except OSError:
            logging.info('%s (%s) already gone.' % (name, pid))

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

        self._kill_if_exists('sky_server_pid', 'sky_server')
        # We could be much more surgical here:
        if 'remote_sky_command_port' in self.pids:
            device = android_commands.AndroidCommands(
                self.pids['device_serial'])
            forwarder.Forwarder.UnmapAllDevicePorts(device)

        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', 'forward', '--remove', port_string])

    def load_command(self, args):
        if not urlparse.urlparse(args.url_or_path).scheme:
            # 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'])
            url = SkyServer.url_for_path(remote_sky_server_port,
                    self.pids['sky_server_root'], args.url_or_path)
        else:
            url = args.url_or_path
        self._send_command_to_sky('/load', url)

    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)
        print response.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._send_command_to_sky(url_path)
        parser.set_defaults(func=command)

    def _wait_for_sky_command_port(self):
        tries = 0
        while True:
            try:
                self._send_command_to_sky('/')
                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', 'logcat', '-s'] + TAGS)

    def main(self):
        logging.basicConfig(level=logging.INFO)
        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.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)

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

        self._add_basic_command(subparsers, 'trace', '/trace',
            'toggle tracing')
        self._add_basic_command(subparsers, 'reload', '/reload',
            'reload the current page')
        self._add_basic_command(subparsers, 'inspect', '/inspect',
            'stop the running sky instance')

        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()
