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

"""XML RPC server for multimedia testing."""

import argparse
import code
import logging
import os
import six.moves.xmlrpc_client
import traceback

import common   # pylint: disable=unused-import
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import logging_config
from autotest_lib.client.cros import constants
from autotest_lib.client.cros import upstart
from autotest_lib.client.cros import xmlrpc_server
from autotest_lib.client.cros.multimedia import assistant_facade_native
from autotest_lib.client.cros.multimedia import audio_facade_native
from autotest_lib.client.cros.multimedia import bluetooth_facade_native
from autotest_lib.client.cros.multimedia import browser_facade_native
from autotest_lib.client.cros.multimedia import cfm_facade_native
from autotest_lib.client.cros.multimedia import display_facade_native
from autotest_lib.client.cros.multimedia import facade_resource
from autotest_lib.client.cros.multimedia import graphics_facade_native
from autotest_lib.client.cros.multimedia import input_facade_native
from autotest_lib.client.cros.multimedia import kiosk_facade_native
from autotest_lib.client.cros.multimedia import system_facade_native
from autotest_lib.client.cros.multimedia import usb_facade_native
from autotest_lib.client.cros.multimedia import video_facade_native


class MultimediaXmlRpcDelegate(xmlrpc_server.XmlRpcDelegate):
    """XML RPC delegate for multimedia testing."""

    def __init__(self, resource):
        """Initializes the facade objects."""

        # TODO: (crbug.com/618111) Add test driven switch for
        # supporting arc_mode enabled or disabled. At this time
        # if ARC build is tested, arc_mode is always enabled.
        arc_res = None
        if utils.get_board_property('CHROMEOS_ARC_VERSION'):
            logging.info('Using ARC resource on ARC enabled board.')
            from autotest_lib.client.cros.multimedia import arc_resource
            arc_res = arc_resource.ArcResource()

        self._facades = {
                'assistant':
                assistant_facade_native.AssistantFacadeNative(resource),
                'audio':
                audio_facade_native.AudioFacadeNative(resource,
                                                      arc_resource=arc_res),
                'bluetooth':
                bluetooth_facade_native.BluetoothFacadeNative(),
                'video':
                video_facade_native.VideoFacadeNative(resource,
                                                      arc_resource=arc_res),
                'display':
                display_facade_native.DisplayFacadeNative(resource),
                'system':
                system_facade_native.SystemFacadeNative(),
                'usb':
                usb_facade_native.USBFacadeNative(),
                'browser':
                browser_facade_native.BrowserFacadeNative(resource),
                'input':
                input_facade_native.InputFacadeNative(),
                'cfm_main_screen':
                cfm_facade_native.CFMFacadeNative(resource, 'hotrod'),
                'cfm_mimo_screen':
                cfm_facade_native.CFMFacadeNative(resource, 'control'),
                'kiosk':
                kiosk_facade_native.KioskFacadeNative(resource),
                'graphics':
                graphics_facade_native.GraphicsFacadeNative()
        }


    def __exit__(self, exception, value, traceback):
        """Clean up the resources."""
        self._facades['audio'].cleanup()


    def _dispatch(self, method, params):
        """Dispatches the method to the proper facade.

        We turn off allow_dotted_names option. The method handles the dot
        and dispatches the method to the proper native facade, like
        DisplayFacadeNative.

        """
        try:
            try:
                if '.' not in method:
                    func = getattr(self, method)
                else:
                    facade_name, method_name = method.split('.', 1)
                    if facade_name in self._facades:
                        func = getattr(self._facades[facade_name], method_name)
                    else:
                        raise Exception('unknown facade: %s' % facade_name)
            except AttributeError:
                raise Exception('method %s not supported' % method)

            logging.info('Dispatching method %s with args %s',
                         str(func), str(params))
            return func(*params)
        except:
            # TODO(ihf): Try to return meaningful stacktraces from the client.
            return traceback.format_exc()


def config_logging():
    """Configs logging to be verbose and use console handler."""
    config = logging_config.LoggingConfig()
    config.configure_logging(use_console=True, verbose=True)


def main():
    """The main function, to run the XMLRPC server."""
    parser = argparse.ArgumentParser()
    parser.add_argument('-d', '--debug', action='store_true', required=False,
                        help=('create a debug console with a ServerProxy "s" '
                              'connecting to the XML RPC sever at localhost'))
    args = parser.parse_args()
    pid = os.getpid()

    if args.debug:
        s = six.moves.xmlrpc_client.ServerProxy('http://localhost:%d' %
                                  constants.MULTIMEDIA_XMLRPC_SERVER_PORT,
                                  allow_none=True)
        code.interact(local=locals())
    else:
        config_logging()
        logging.debug('multimedia_xmlrpc_server[%s] main...', pid)
        xmlrpc_server.terminate_old(__file__)

        # bind before full setup, so the error is the last thing in the log
        server = xmlrpc_server.XmlRpcServer(
                'localhost', constants.MULTIMEDIA_XMLRPC_SERVER_PORT)

        # Restart Cras to clean up any audio activities.
        upstart.restart_job('cras')

        with facade_resource.FacadeResource() as res:
            server.register_delegate(MultimediaXmlRpcDelegate(res))
            server.run()
            logging.debug('multimedia_xmlrpc_server[%s] exiting...', pid)
        logging.debug('multimedia_xmlrpc_server[%s] done.\n', pid)


if __name__ == '__main__':
    main()
