# Copyright 2014 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.

import httplib
import logging
import socket
import xmlrpclib
import pprint
import sys

from autotest_lib.client.common_lib.cros import retry
from autotest_lib.client.cros import constants
from autotest_lib.server import autotest
from autotest_lib.server.cros.multimedia import audio_facade_adapter
from autotest_lib.server.cros.multimedia import display_facade_adapter


class _Method:
    """Class to save the name of the RPC method instead of the real object.

    It keeps the name of the RPC method locally first such that the RPC method
    can be evalulated to a real object while it is called. Its purpose is to
    refer to the latest RPC proxy as the original previous-saved RPC proxy may
    be lost due to reboot.

    The call_method is the method which does refer to the latest RPC proxy.
    """
    def __init__(self, call_method, name):
        self.__call_method = call_method
        self.__name = name

    def __getattr__(self, name):
        # Support a nested method.
        return _Method(self.__call_method, "%s.%s" % (self.__name, name))

    def __call__(self, *args, **dargs):
        return self.__call_method(self.__name, *args, **dargs)


class RemoteFacadeProxy(object):
    """An abstraction of XML RPC proxy to the DUT multimedia server.

    The traditional XML RPC server proxy is static. It is lost when DUT
    reboots. This class reconnects the server again when it finds the
    connection is lost.

    """

    XMLRPC_CONNECT_TIMEOUT = 60
    XMLRPC_RETRY_TIMEOUT = 180
    XMLRPC_RETRY_DELAY = 10

    def __init__(self, host):
        """Construct a RemoteFacadeProxy.

        @param host: Host object representing a remote host.
        """
        self._client = host
        self._xmlrpc_proxy = None
        self.connect(reconnect=False)


    def __getattr__(self, name):
        """Return a _Method object only, not its real object."""
        return _Method(self.__call_proxy, name)


    def __call_proxy(self, name, *args, **dargs):
        """Make the call on the latest RPC proxy object.

        This method gets the internal method of the RPC proxy and calls it.

        @param name: Name of the RPC method, a nested method supported.
        @param args: The rest of arguments.
        @param dargs: The rest of dict-type arguments.
        @return: The return value of the RPC method.
        """
        try:
            # TODO(ihf): This logs all traffic from server to client. Make the spew optional.
            rpc = (
                '%s(%s, %s)' %
                (pprint.pformat(name), pprint.pformat(args),
                 pprint.pformat(dargs)))
            try:
                value = getattr(self._xmlrpc_proxy, name)(*args, **dargs)
                if type(value) is str and value.startswith('Traceback'):
                    raise Exception('RPC error: %s\n%s' % (name, value))
                logging.info('RPC %s returns %s.', rpc, pprint.pformat(value))
                return value
            except (socket.error,
                    xmlrpclib.ProtocolError,
                    httplib.BadStatusLine):
                # Reconnect the RPC server in case connection lost, e.g. reboot.
                self.connect(reconnect=True)
                # Try again.
                logging.warning('Retrying RPC %s.', rpc)
                value = getattr(self._xmlrpc_proxy, name)(*args, **dargs)
                if type(value) is str and value.startswith('Traceback'):
                    raise Exception('RPC error: %s\n%s' % (name, value))
                logging.info('RPC %s returns %s.', rpc, pprint.pformat(value))
                return value
        except:
            logging.error(
                'Failed RPC %s with status [%s].', rpc, sys.exc_info()[0])
            raise


    def connect(self, reconnect):
        """Connects the XML-RPC proxy on the client.

        @param reconnect: True for reconnection, False for the first-time.
        """
        @retry.retry((socket.error,
                      xmlrpclib.ProtocolError,
                      httplib.BadStatusLine),
                      timeout_min=self.XMLRPC_RETRY_TIMEOUT / 60.0,
                      delay_sec=self.XMLRPC_RETRY_DELAY)
        def connect_with_retries(reconnect):
            """Connects the XML-RPC proxy with retries.

            @param reconnect: True for reconnection, False for the first-time.
            """
            if reconnect:
                command = constants.MULTIMEDIA_XMLRPC_SERVER_RESTART_COMMAND
            else:
                command = constants.MULTIMEDIA_XMLRPC_SERVER_COMMAND

            self._xmlrpc_proxy = self._client.xmlrpc_connect(
                    command,
                    constants.MULTIMEDIA_XMLRPC_SERVER_PORT,
                    command_name=(
                        constants.MULTIMEDIA_XMLRPC_SERVER_CLEANUP_PATTERN
                    ),
                    ready_test_name=(
                        constants.MULTIMEDIA_XMLRPC_SERVER_READY_METHOD),
                    timeout_seconds=self.XMLRPC_CONNECT_TIMEOUT)

        logging.info('Setup the connection to RPC server, with retries...')
        connect_with_retries(reconnect)


    def __del__(self):
        """Destructor of RemoteFacadeFactory."""
        self._client.rpc_disconnect(
                constants.MULTIMEDIA_XMLRPC_SERVER_PORT)


class RemoteFacadeFactory(object):
    """A factory to generate remote multimedia facades.

    The facade objects are remote-wrappers to access the DUT multimedia
    functionality, like display, video, and audio.

    """

    def __init__(self, host):
        """Construct a RemoteFacadeFactory.

        @param host: Host object representing a remote host.
        """
        self._client = host
        # Make sure the client library is on the device so that the proxy code
        # is there when we try to call it.
        client_at = autotest.Autotest(self._client)
        client_at.install()
        self._proxy = RemoteFacadeProxy(self._client)


    def create_audio_facade(self):
        """Creates an audio facade object."""
        return audio_facade_adapter.AudioFacadeRemoteAdapter(
                self._client, self._proxy)


    def create_display_facade(self):
        """Creates a display facade object."""
        return display_facade_adapter.DisplayFacadeRemoteAdapter(
                self._client, self._proxy)
