# Copyright 2019 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 common
import logging
from autotest_lib.client.common_lib import hosts
from autotest_lib.server.hosts import cros_constants
from autotest_lib.server.hosts import repair_utils
from autotest_lib.client.common_lib import utils

from chromite.lib import timeout_util

try:
    from chromite.lib import metrics
except ImportError:
    metrics = utils.metrics_mock

# There are some labstations we don't want they receive auto-update,
# e.g. labstations that used for image qualification purpose
UPDATE_EXEMPTED_POOL = {'servo_verification', 'labstation_tryjob'}


class _LabstationUpdateVerifier(hosts.Verifier):
    """
    Verifier to trigger a labstation update, if necessary.

    The operation doesn't wait for the update to complete and is
    considered a success whether or not the servo is currently
    up-to-date.
    """

    @timeout_util.TimeoutDecorator(cros_constants.LONG_VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        """First, only run this verifier if the host is in the physical lab.
        Secondly, skip if the test is being run by test_that, because subnet
        restrictions can cause the update to fail.
        """
        if host.is_in_lab() and host.job and host.job.in_lab:
            host.update_cros_version_label()
            info = host.host_info_store.get()
            if bool(UPDATE_EXEMPTED_POOL & info.pools):
                logging.info("Skip update because the labstation is in"
                             " one of following exempted pool: %s", info.pools)
                return

            stable_version = info.stable_versions.get('cros')
            if stable_version:
                host.update_image(stable_version=stable_version)
            else:
                raise hosts.AutoservVerifyError('Failed to check/update'
                                                ' labstation due to no stable'
                                                '_version found in host_info'
                                                '_store.')

    @property
    def description(self):
        return 'Labstation image is updated to current stable-version'


class _LabstationRebootVerifier(hosts.Verifier):
    """Check if reboot is need for the labstation and perform a reboot if it's
    not currently using by any tests.
    """

    @timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        if host.is_reboot_requested():
            host.try_reboot()

    @property
    def description(self):
        return 'Reboot labstation if requested and the labstation is not in use'


class _LabstationLangidVerifier(hosts.Verifier):
    """Check if labstation has issue with read serial from servo devices.

    TODO(b:162518926): remove when bug will be resolved.
    """

    @timeout_util.TimeoutDecorator(cros_constants.VERIFY_TIMEOUT_SEC)
    def verify(self, host):
        try:
            cmd = (
                    "python2 -c 'import usb;"
                    " print([[d.open().getString(d.iSerialNumber, 128)"
                    " for d in bus.devices if d.idVendor == 0x18d1"
                    " and (d.idProduct == 0x501b"  #servo_v4
                    " or d.idProduct == 0x501a"  #servo_micro
                    " or d.idProduct == 0x5014)"  #ccd_cr50
                    " and d.iSerialNumber == 3]"  # 3 - slot for serial
                    " for bus in usb.busses()])'")
            result = host.run(cmd, ignore_status=True, timeout=30)
            if result.exit_status == 0:
                return
            if 'The device has no langid' in result.stderr.strip():
                self._mark_host_for_reboot(host)
        except Exception as e:
            logging.debug('(Not critical) %s', e)
            if 'Timeout encountered' in str(e):
                # Time out mean we cannot get servo attributes in time because
                # one of the servos has langid.
                self._mark_host_for_reboot(host)

    def _mark_host_for_reboot(self, host):
        """Mark Labstation as has issue with langid."""
        logging.info('Detected langid issue.')
        data = {'host': host.hostname, 'board': host.get_board() or ''}
        metrics.Counter('chromeos/autotest/labstation/langid_issue').increment(
                fields=data)
        # labstation reboot will fix the issue but we does not want to
        # reboot the labstation to often. Just create request to reboot
        # it for the next time.
        logging.info('Created request for reboot.')
        cmd = ('touch %slangid%s' %
               (host.TEMP_FILE_DIR, host.REBOOT_FILE_POSTFIX))
        host.run(cmd, ignore_status=True, timeout=30)

    @property
    def description(self):
        return 'Check if labsattion has langid issue'


def create_labstation_repair_strategy():
    """
    Return a `RepairStrategy` for a `LabstationHost`.
    """
    verify_dag = [
            (repair_utils.SshVerifier, 'ssh', []),
            (_LabstationUpdateVerifier, 'update', ['ssh']),
            (_LabstationLangidVerifier, 'langid', ['ssh']),
            (_LabstationRebootVerifier, 'reboot', ['ssh']),
    ]

    repair_actions = [
        (repair_utils.RPMCycleRepair, 'rpm', [], ['ssh', 'reboot']),
    ]
    return hosts.RepairStrategy(verify_dag, repair_actions, 'labstation')
