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

import httplib
import logging
import socket
import time
import xmlrpclib

from autotest_lib.client.cros.faft.config import Config as ClientConfig
from autotest_lib.server import autotest


class _Method(object):
    """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)

    def __repr__(self):
        """Return a description of the method object"""
        return "%s('%s')" % (self.__class__.__name__, self.__name)

    def __str__(self):
        """Return a description of the method object"""
        return "<%s '%s'>" % (self.__class__.__name__, self.__name)


class RPCProxy(object):
    """Proxy to the FAFTClient RPC server on DUT.

    It acts as a proxy to the FAFTClient on DUT. It is smart enough to:
     - postpone the RPC connection to the first class method call;
     - reconnect to the RPC server in case connection lost, e.g. reboot;
     - always call the latest RPC proxy object.

     @ivar _client: the ssh host object
     @type host: autotest_lib.server.hosts.abstract_ssh.AbstractSSHHost
     @ivar _faft_client: the real serverproxy to use for calls
     @type _faft_client: xmlrpclib.ServerProxy | None
    """
    _client_config = ClientConfig()

    def __init__(self, host):
        """Constructor.

        @param host: The host object, passed via the test control file.
        """
        self._client = host
        self._faft_client = None

    def __del__(self):
        self.disconnect()

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

    def __call_faft_client(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 FAFTClient RPC method.
        """
        if self._faft_client is None:
            self.connect()
        try:
            return getattr(self._faft_client, name)(*args, **dargs)
        except (socket.error,
                httplib.BadStatusLine,
                xmlrpclib.ProtocolError):
            # Reconnect the RPC server in case connection lost, e.g. reboot.
            self.connect()
            # Try again.
            return getattr(self._faft_client, name)(*args, **dargs)

    def connect(self):
        """Connect the RPC server."""
        # Make sure Autotest dependency is there.
        autotest.Autotest(self._client).install()
        self._faft_client = self._client.rpc_server_tracker.xmlrpc_connect(
                self._client_config.rpc_command,
                self._client_config.rpc_port,
                command_name=self._client_config.rpc_command_short,
                ready_test_name=self._client_config.rpc_ready_call,
                timeout_seconds=self._client_config.rpc_timeout,
                logfile="%s.%s" % (self._client_config.rpc_logfile,
                                   time.time()),
                server_desc=str(self)
                )

    def disconnect(self):
        """Disconnect the RPC server."""
        # The next start of the RPC server will terminate any leftovers,
        # so no need to pkill upon disconnect.
        if self._faft_client is not None:
            logging.debug("Closing FAFT RPC server connection.")
        self._client.rpc_server_tracker.disconnect(
                self._client_config.rpc_port, pkill=False)
        self._faft_client = None

    def quit(self):
        """Tell the RPC server to quit, then disconnect from it."""
        if self._faft_client is None:
            return
        logging.debug("Telling FAFT RPC server to quit.")
        try:
            remote_quit = getattr(
                    self._faft_client, self._client_config.rpc_quit_call)
            remote_quit()
            need_pkill = False
        except (StandardError, httplib.BadStatusLine, xmlrpclib.Error) as e:
            logging.warn("Error while telling FAFT RPC server to quit: %s", e)
            # If we failed to tell the RPC server to quit for some reason,
            # fall back to SIGTERM, because it may not have exited.
            need_pkill = True

        self._client.rpc_server_tracker.disconnect(
                self._client_config.rpc_port, pkill=need_pkill)
        self._faft_client = None

    def __repr__(self):
        """Return a description of the proxy object"""
        return '%s(%s)' % (self.__class__.__name__, self._client)

    def __str__(self):
        """Return a description of the proxy object"""
        return "<%s '%s:%s'>" % (
                self.__class__.__name__,
                self._client.hostname,
                self._client_config.rpc_port)
