# Copyright 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 test remotely emulates noisy HPD line when connecting to an external
display in extended mode using the Chameleon board."""

import logging
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.chameleon import chameleon_port_finder
from autotest_lib.client.cros.chameleon import chameleon_screen_test
from autotest_lib.server import test
from autotest_lib.server.cros.multimedia import remote_facade_factory


class display_HotPlugNoisy(test.test):
    """Noisy display HPD test.

    This test talks to a Chameleon board and a DUT to set up, run, and verify
    DUT behavior in response to noisy HPD line.
    """
    version = 1
    PLUG_CONFIGS = [
        # (plugged_before_noise, plugged_after_noise)

        (False, False),
        (False, True),
        (True, False),
        (True, True),
    ]

    # pulse segments in msec that end with plugged state
    PULSES_PLUGGED = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
    # pulse segments in msec that end with unplugged state
    PULSES_UNPLUGGED = PULSES_PLUGGED + [2048]

    REPLUG_DELAY_SEC = 1


    def run_once(self, host, test_mirrored=False):
        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.reset()
        finder = chameleon_port_finder.ChameleonVideoInputFinder(
                chameleon_board, display_facade)

        errors = []
        warns = []
        for chameleon_port in finder.iterate_all_ports():
            screen_test = chameleon_screen_test.ChameleonScreenTest(
                    chameleon_port, display_facade, self.outputdir)

            logging.info('See the display on Chameleon: port %d (%s)',
                         chameleon_port.get_connector_id(),
                         chameleon_port.get_connector_type())

            logging.info('Set mirrored: %s', test_mirrored)
            display_facade.set_mirrored(test_mirrored)

            # Keep the original connector name, for later comparison.
            expected_connector = display_facade.get_external_connector_name()
            resolution = display_facade.get_external_resolution()
            logging.info('See the display on DUT: %s (%dx%d)',
                         expected_connector, *resolution)

            for (plugged_before_noise,
                 plugged_after_noise) in self.PLUG_CONFIGS:
                logging.info('TESTING THE CASE: %s > noise > %s',
                             'plug' if plugged_before_noise else 'unplug',
                             'plug' if plugged_after_noise else 'unplug')

                chameleon_port.set_plug(plugged_before_noise)

                if screen_test.check_external_display_connected(
                        expected_connector if plugged_before_noise else False,
                        errors):
                    # Skip the following test if an unexpected display detected.
                    continue

                chameleon_port.fire_mixed_hpd_pulses(
                        self.PULSES_PLUGGED if plugged_after_noise
                                            else self.PULSES_UNPLUGGED)

                if plugged_after_noise:
                    err = screen_test.check_external_display_connected(
                            expected_connector)

                    if not err:
                        if chameleon_port.wait_video_input_stable():
                            err = screen_test.test_screen_with_image(
                                    resolution, test_mirrored)
                        else:
                            err = 'video input not stable'
                    if err:
                        # When something goes wrong after the noise, a normal
                        # user would try to re-plug the cable to recover.
                        # We emulate this behavior below and report error if
                        # the problem persists.
                        logging.warn('Possibly flaky: %s', err)
                        warns.append('Possibly flaky: %s' % err)
                        logging.info('Replug and retry the screen test...')
                        chameleon_port.unplug()
                        time.sleep(self.REPLUG_DELAY_SEC)
                        chameleon_port.plug()
                        chameleon_port.wait_video_input_stable()
                        screen_test.test_screen_with_image(
                                resolution, test_mirrored, errors)
                else:
                    screen_test.check_external_display_connected(False, errors)
                    time.sleep(1)

        if errors:
            raise error.TestFail('; '.join(set(errors)))
        elif warns:
            raise error.TestWarn('; '.join(set(warns)))
