# 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):
        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
                    and 'The device has no langid' in result.stderr.strip()):
            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')
