# Copyright (c) 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.
#

"""This file provides core logic for connecting a Chameleon Daemon."""

import logging

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import global_config
from autotest_lib.client.cros.chameleon import chameleon
from autotest_lib.server.cros import dnsname_mangler
from autotest_lib.server.cros.dynamic_suite import frontend_wrappers
from autotest_lib.server.hosts import ssh_host


# Names of the host attributes in the database that represent the values for
# the chameleon_host and chameleon_port for a servo connected to the DUT.
CHAMELEON_HOST_ATTR = 'chameleon_host'
CHAMELEON_PORT_ATTR = 'chameleon_port'

_CONFIG = global_config.global_config
ENABLE_SSH_TUNNEL_FOR_CHAMELEON = _CONFIG.get_config_value(
        'CROS', 'enable_ssh_tunnel_for_chameleon', type=bool, default=False)

class ChameleonHostError(Exception):
    """Error in ChameleonHost."""
    pass


class ChameleonHost(ssh_host.SSHHost):
    """Host class for a host that controls a Chameleon."""

    # Chameleond process name.
    CHAMELEOND_PROCESS = 'chameleond'


    # TODO(waihong): Add verify and repair logic which are required while
    # deploying to Cros Lab.


    def _initialize(self, chameleon_host='localhost', chameleon_port=9992,
                    *args, **dargs):
        """Initialize a ChameleonHost instance.

        A ChameleonHost instance represents a host that controls a Chameleon.

        @param chameleon_host: Name of the host where the chameleond process
                               is running.
                               If this is passed in by IP address, it will be
                               treated as not in lab.
        @param chameleon_port: Port the chameleond process is listening on.

        """
        super(ChameleonHost, self)._initialize(hostname=chameleon_host,
                                               *args, **dargs)

        self._is_in_lab = None
        self._check_if_is_in_lab()

        self._chameleon_port = chameleon_port
        self._local_port = None
        self._tunneling_process = None

        try:
            if self._is_in_lab and not ENABLE_SSH_TUNNEL_FOR_CHAMELEON:
                self._chameleon_connection = chameleon.ChameleonConnection(
                        self.hostname, chameleon_port)
            else:
                # A proxy generator is passed as an argument so that a proxy
                # could be re-created on demand in ChameleonConnection
                # whenever needed, e.g., after a reboot.
                proxy_generator = (
                        lambda: self.rpc_server_tracker.xmlrpc_connect(
                                None, chameleon_port,
                                ready_test_name=chameleon.CHAMELEON_READY_TEST,
                                timeout_seconds=60))
                self._chameleon_connection = chameleon.ChameleonConnection(
                        None, proxy_generator=proxy_generator)

        except Exception as e:
            raise ChameleonHostError('Can not connect to Chameleon: %s(%s)',
                                     e.__class__, e)


    def _check_if_is_in_lab(self):
        """Checks if Chameleon host is in lab and set self._is_in_lab.

        If self.hostname is an IP address, we treat it as is not in lab zone.

        """
        self._is_in_lab = (False if dnsname_mangler.is_ip_address(self.hostname)
                           else utils.host_is_in_lab_zone(self.hostname))


    def is_in_lab(self):
        """Check whether the chameleon host is a lab device.

        @returns: True if the chameleon host is in Cros Lab, otherwise False.

        """
        return self._is_in_lab


    def get_wait_up_processes(self):
        """Get the list of local processes to wait for in wait_up.

        Override get_wait_up_processes in
        autotest_lib.client.common_lib.hosts.base_classes.Host.
        Wait for chameleond process to go up. Called by base class when
        rebooting the device.

        """
        processes = [self.CHAMELEOND_PROCESS]
        return processes


    def create_chameleon_board(self):
        """Create a ChameleonBoard object with error recovery.

        This function will reboot the chameleon board once and retry if we can't
        create chameleon board.

        @return A ChameleonBoard object.
        """
        # TODO(waihong): Add verify and repair logic which are required while
        # deploying to Cros Lab.
        chameleon_board = None
        try:
            chameleon_board = chameleon.ChameleonBoard(
                    self._chameleon_connection, self)
            return chameleon_board
        except:
            self.reboot()
            chameleon_board = chameleon.ChameleonBoard(
                self._chameleon_connection, self)
            return chameleon_board


def create_chameleon_host(dut, chameleon_args):
    """Create a ChameleonHost object.

    There three possible cases:
    1) If the DUT is in Cros Lab and has a chameleon board, then create
       a ChameleonHost object pointing to the board. chameleon_args
       is ignored.
    2) If not case 1) and chameleon_args is neither None nor empty, then
       create a ChameleonHost object using chameleon_args.
    3) If neither case 1) or 2) applies, return None.

    @param dut: host name of the host that chameleon connects. It can be used
                to lookup the chameleon in test lab using naming convention.
                If dut is an IP address, it can not be used to lookup the
                chameleon in test lab.
    @param chameleon_args: A dictionary that contains args for creating
                           a ChameleonHost object,
                           e.g. {'chameleon_host': '172.11.11.112',
                                 'chameleon_port': 9992}.

    @returns: A ChameleonHost object or None.

    """
    if not utils.is_in_container():
        is_moblab = utils.is_moblab()
    else:
        is_moblab = _CONFIG.get_config_value(
                'SSP', 'is_moblab', type=bool, default=False)

    if not is_moblab:
        dut_is_hostname = not dnsname_mangler.is_ip_address(dut)
        if dut_is_hostname:
            chameleon_hostname = chameleon.make_chameleon_hostname(dut)
            if utils.host_is_in_lab_zone(chameleon_hostname):
                # Be more tolerant on chameleon in the lab because
                # we don't want dead chameleon blocks non-chameleon tests.
                if utils.ping(chameleon_hostname, deadline=3):
                   logging.warning(
                           'Chameleon %s is not accessible. Please file a bug'
                           ' to test lab', chameleon_hostname)
                   return None
                return ChameleonHost(chameleon_host=chameleon_hostname)
        if chameleon_args:
            return ChameleonHost(**chameleon_args)
        else:
            return None
    else:
        afe = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
        hosts = afe.get_hosts(hostname=dut)
        if hosts and CHAMELEON_HOST_ATTR in hosts[0].attributes:
            return ChameleonHost(
                chameleon_host=hosts[0].attributes[CHAMELEON_HOST_ATTR],
                chameleon_port=hosts[0].attributes.get(
                    CHAMELEON_PORT_ATTR, 9992)
            )
        else:
            return None


def create_btpeer_host(dut, btpeer_args_list):
    """Create a ChameleonHost object for a Bluetooth peer

    This is similar to create_chameleon_host but unlike chameleon board
    there can be multiple btpeers with a single DUT

    There four possible cases:
    1) If the DUT is in Cros Lab then assume that it can have up to 4 bluetooth
       peers. Ping the url and create a Chameleon host for each Bluetooth peer
       present. btpeer_args_list is ignored.
    2) If not case 1) and btpeer_args_list is not empty, then
       create a BtpeerHost object for each host specified in btpeer_args_list.
    3) If neither case 1) or 2) applies, return None.
    4) This DUT is controlled  by moblab. This case is not implemented.


    @param dut: host name of the host that btpeer connects. It can be used
                to lookup the btpeer in test lab using naming convention.
                If dut is an IP address, it can not be used to lookup the
                btpeer in test lab. Naming convention in the lab is
                <hostname>-btpeer[1-4]
    @param btpeer_args_list: A list of dictionaries that contains args for
                            creating a BtpeerHost object,
                           e.g. {'btpeer_host': '172.11.11.112',
                                 'btpeer_port': 9992}.

    @returns: A list of BtpeerHost objects

    """
    def _convert_btpeer_args(args):
        """Convert btpeer args to format accepted by ChameleonHost."""
        ret_args = {}
        if 'btpeer_host' in args:
            ret_args['chameleon_host'] = args['btpeer_host']
        if 'btpeer_port' in args:
            ret_args['chameleon_port'] = args['btpeer_port']
        return ret_args

    if not utils.is_in_container():
        is_moblab = utils.is_moblab()
    else:
        is_moblab = _CONFIG.get_config_value(
                'SSP', 'is_moblab', type=bool, default=False)

    btpeer_hosts = []

    if not is_moblab:
        if (not dnsname_mangler.is_ip_address(dut) and
            utils.host_is_in_lab_zone(dut)):
            # This is a device in the lab. Ignore any arguments passed and
            # derive peer hostnames from the DUT hostname
            btpeer_hostnames = chameleon.make_btpeer_hostnames(dut)
            for btpeer_hostname in btpeer_hostnames:
                # Not all test bed have 4 Bluetooth peers
                if utils.ping(btpeer_hostname, deadline=3):
                    logging.warning('Btpeer %s is not accessible. This maybe '
                                    'expected or it maybe an issue with the '
                                    'Bluetooth peer. Please Check the test bed.'
                                    , btpeer_hostname)
                    continue
                else:
                    logging.debug("Creating btpeer from %s",btpeer_hostname)
                    btpeer_hosts.append(
                        ChameleonHost(chameleon_host=btpeer_hostname))
            return btpeer_hosts
        else:
            # IP address given or DNS address is not in lab.
            # Create the Bluetooth peers from the arguments passed
            return [ ChameleonHost(**_convert_btpeer_args(btpeer_args))
                     for btpeer_args in btpeer_args_list]
    else:
        # TODO(b:149606762)
        # moblab still create Bluetooth peer from chameleon_args
        afe = frontend_wrappers.RetryingAFE(timeout_min=5, delay_sec=10)
        hosts = afe.get_hosts(hostname=dut)
        if hosts and CHAMELEON_HOST_ATTR in hosts[0].attributes:
            return [ChameleonHost(
                chameleon_host=hosts[0].attributes[CHAMELEON_HOST_ATTR],
                chameleon_port=hosts[0].attributes.get(
                    CHAMELEON_PORT_ATTR, 9992)
            )]
        else:
            return []
