# Copyright 2017 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 time
import random

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.cfm import cfm_base_test
from autotest_lib.client.common_lib.cros import power_cycle_usb_util
from autotest_lib.client.common_lib.cros.cfm.usb import cfm_usb_devices
from autotest_lib.client.common_lib.cros.cfm.usb import usb_device_collector

LONG_TIMEOUT = 20
SHORT_TIMEOUT = 5


class enterprise_CFM_MimoCheck(cfm_base_test.CfmBaseTest):
    """Tests the following fuctionality works on CFM enrolled devices:
           1. Verify CfM has Camera, Speaker and Mimo connected.
           2. Verify all peripherals have expected usb interfaces.
           3. Verify after rebooting CfM Mimo is present.
           4. Verify after powercycle Mimo Mimo comes back.
    """
    version = 1

    def _power_cycle_mimo_device(self):
        """Power Cycle Mimo device"""
        logging.info('Plan to power cycle Mimo')
        try:
            power_cycle_usb_util.power_cycle_usb_vidpid(
                    self._host, self._board, self._mimo.vendor_id,
                    self._mimo.product_id)
        except KeyError:
            raise error.TestFail('Could not find target device: %s',
                                 self._mimo.product)

    def _test_power_cycle_mimo(self):
        """Power Cycle Mimo device for multiple times"""
        self._power_cycle_mimo_device()
        logging.info('Powercycle done for %s (%s)', self._mimo.product,
                     self._mimo.vid_pid)
        time.sleep(LONG_TIMEOUT)
        self._kernel_usb_functional_test()

    def _check_peripherals(self):
        """
        Check CfM has camera, speaker and MiMO connected.
        @returns list of peripherals found.
        """
        atruses = self.device_collector.get_devices_by_spec(
                cfm_usb_devices.ATRUS)
        if not atruses:
            raise error.TestFail('Expected to find connected speakers.')
        self._atrus = atruses[0]

        huddlys = self.device_collector.get_devices_by_spec(
                cfm_usb_devices.HUDDLY_GO)
        if not huddlys:
            raise error.TestFail('Expected to find a connected camera.')
        self._huddly = huddlys[0]

        displays = self.device_collector.get_devices_by_spec(
                *cfm_usb_devices.ALL_MIMO_DISPLAYS)
        if not displays:
            raise error.TestFail('Expected a MiMO display to be connected.')
        if len(displays) != 1:
            raise error.TestFail('Expected exactly one MiMO display to be '
                                 'connected. Found %d' % len(displays))
        self._mimo = displays[0]

        controllers = self.device_collector.get_devices_by_spec(
                cfm_usb_devices.MIMO_VUE_HID_TOUCH_CONTROLLER)
        if not controllers:
            raise error.TestFail('Expected a MiMO controller to be connected.')
        if len(controllers) != 1:
            raise error.TestFail('Expected exactly one MiMO controller to be '
                                 'connected. Found %d' % len(controllers))
        self._touch_controller = controllers[0]

    def _check_device_interfaces_match_spec(self, spec):
        for device in self.device_collector.get_devices_by_spec(spec):
            if not device.interfaces_match_spec(spec):
                raise error.TestFail(
                        'Device %s has unexpected interfaces.'
                        'Expected: %s. Actual: %s' %
                        (device, spec.interfaces, spec.interfaces))

    def _kernel_usb_functional_test(self):
        """
        Check connected camera, speaker and Mimo have expected usb interfaces.
        """
        self._check_device_interfaces_match_spec(self._atrus)
        self._check_device_interfaces_match_spec(self._huddly)
        self._check_device_interfaces_match_spec(self._mimo)
        self._check_device_interfaces_match_spec(self._touch_controller)

    def _test_reboot(self):
        """Reboot testing for Mimo."""

        boot_id = self._host.get_boot_id()
        self._host.reboot()
        self._host.wait_for_restart(old_boot_id=boot_id)
        self.cfm_facade.restart_chrome_for_cfm()
        time.sleep(SHORT_TIMEOUT)
        self.cfm_facade.wait_for_telemetry_commands()
        self._kernel_usb_functional_test()

    def _test_mimo_in_call(self):
        """
        Start a hangout session and end the session after random time.

        @raises error.TestFail if any of the checks fail.
        """
        logging.info('Joining meeting...')
        if self._is_meeting:
            self.cfm_facade.start_meeting_session()
        else:
            self.cfm_facade.start_new_hangout_session('mimo-functional-test')
        time.sleep(random.randrange(SHORT_TIMEOUT, LONG_TIMEOUT))

        # Verify USB data in-call.
        self._kernel_usb_functional_test()

        if self._is_meeting:
            self.cfm_facade.end_meeting_session()
        else:
            self.cfm_facade.end_hangout_session()
        logging.info('Session has ended.')

        # Verify USB devices after leaving the call.
        self._kernel_usb_functional_test()
        time.sleep(SHORT_TIMEOUT)

    def run_once(self, repetitions, is_meeting):
        """
        Runs the test.

        @param repetitions: amount of reboot cycles to perform.
        """
        # Remove 'board:' prefix.
        self._board = self._host.get_board().split(':')[1]
        self._is_meeting = is_meeting

        self.device_collector = usb_device_collector.UsbDeviceCollector(
                self._host)
        self._check_peripherals()
        self._kernel_usb_functional_test()

        self.cfm_facade.wait_for_telemetry_commands()

        for i in range(1, repetitions + 1):
            logging.info('Running test cycle %d/%d', i, repetitions)
            self._test_reboot()
            self._test_mimo_in_call()
            self._test_power_cycle_mimo()
