# Lint as: python2, python3
# 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.host = 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.host).install()
        self._faft_client = self.host.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.host.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 Exception as e:
            logging.warning("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.host.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.host)

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