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

sys.path.insert(0, os.path.join(Paths('ignored').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.paths = None
        self.pids = {}

    def _server_root_for_url(self, url_or_path):
        path = os.path.abspath(url_or_path)
        if os.path.commonprefix([path, self.paths.src_root]) == self.paths.src_root:
            server_root = self.paths.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

        # FIXME: This doesn't work for android
        if args.gdb:
            shell_command = ['gdb', '--args'] + shell_command

        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):
        # FIXME: Lame that we use self for a command-specific variable.
        self.paths = Paths(args.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 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):
        try:
            self._send_command_to_sky('/quit')
        except:
            pass
        # Kill the mojo process for good measure. :)
        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 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)

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