# Copyright 2016 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
import socket

import common
from autotest_lib.client.common_lib import hosts
from autotest_lib.server import utils
from autotest_lib.server.hosts import servo_constants
from autotest_lib.server.hosts import cros_constants

from chromite.lib import timeout_util


def require_servo(host, ignore_state=False):
    """Require a DUT to have a working servo for a repair action.

    @param host             Host object that require servo.
    @param ignore_state     Ignore servo state as long as the we still have
                            servo connection. Some non-critical verifier
                            failures may not cause servo connection been
                            disconnected.
    """
    servo_initialized = host.servo is not None
    servo_working = (host.get_servo_state() ==
                     servo_constants.SERVO_STATE_WORKING or ignore_state)

    if not (servo_initialized and servo_working):
        raise hosts.AutoservRepairError(
                '%s has no working servo.' % host.hostname, 'no_working_servo')
    logging.info('Servo dependence is available for the RepairAction/test.')


class SshVerifier(hosts.Verifier):
    """
    Verifier to test a host's accessibility via `ssh`.

    This verifier checks whether a given host is reachable over `ssh`.
    In the event of failure, it distinguishes one of three distinct
    conditions:
      * The host can't be found with a DNS lookup.
      * The host doesn't answer to ping.
      * The host answers to ping, but not to ssh.
    """

    @timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        if host.is_up():
            return
        msg = 'No answer to ssh from %s'
        try:
            socket.gethostbyname(host.hostname)
        except Exception as e:
            logging.exception('DNS lookup failure')
            msg = 'Unable to look up %%s in DNS: %s' % e
        else:
            if utils.ping(host.hostname, tries=1, deadline=1) != 0:
                msg = 'No answer to ping from %s'
        raise hosts.AutoservVerifyError(msg % host.hostname)

    @property
    def description(self):
        return 'host is available via ssh'


class PingVerifier(hosts.Verifier):
    """
    Verifier to test a host's accessibility via `ping`.

    This verifier checks whether a given host is reachable over `ping`.
    The device is pingable as soon as booted to level when network driver
    can respond.
    In the event of failure, it distinguishes one of distinct conditions:
      * The host can't be found with a DNS lookup.
      * The host doesn't booted with network drivers.
    """

    @timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        if host.is_up_fast(count=10):
            return
        msg = 'No answer to ping to %s'
        ip_address = None
        try:
            ip_address = socket.gethostbyname(host.hostname)
        except Exception as e:
            logging.exception('DNS lookup failure')
            msg = 'Unable to look up %s in DNS: %s' % (host.hostname, str(e))
            raise hosts.AutoservVerifyError(msg)
        if not ip_address:
            msg = 'Hostname: %s not present in DNS' % host.hostname
            raise hosts.AutoservVerifyError(msg)

    @property
    def description(self):
        return 'host is available via ping'


class LegacyHostVerifier(hosts.Verifier):
    """
    Ask a Host instance to perform its own verification.

    This class exists as a temporary legacy during refactoring to
    provide access to code that hasn't yet been rewritten to use the new
    repair and verify framework.
    """

    @timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        host.verify_software()
        host.verify_hardware()

    @property
    def description(self):
        return 'Legacy host verification checks'


class RebootRepair(hosts.RepairAction):
    """Repair a target device by rebooting it."""

    # Timeout of this action should defined in child class.
    def repair(self, host):
        host.reboot()

    @property
    def description(self):
        return 'Reboot the host'


class RPMCycleRepair(hosts.RepairAction):
    """
    Cycle AC power using the RPM infrastructure.

    This is meant to catch two distinct kinds of failure:
      * If the target has no battery (that is, a chromebox), power
        cycling it may force it back on.
      * If the target has a batter that is discharging or even fully
        drained, power cycling will leave power on, enabling other
        repair procedures.
    """

    @timeout_util.TimeoutDecorator(cros_constants.REPAIR_TIMEOUT_SEC)
    def repair(self, host):
        if not host.has_power():
            raise hosts.AutoservRepairError(
                    '%s has no RPM connection.' % host.hostname,
                    'no_working_rpm')
        host.power_cycle()


    @property
    def description(self):
        return 'Power cycle the host with RPM'
