# 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 logging
from six.moves import http_client as httplib
import socket
import time
from six.moves import xmlrpc_client as 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),
                request_timeout_seconds=self._client_config.
                rpc_request_timeout,
        )

    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)
