# 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.bin import utils
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):
        if test_mirrored and not host.get_board_type() == 'CHROMEBOOK':
            raise error.TestNAError('DUT is not Chromebook. Test Skipped')

        factory = remote_facade_factory.RemoteFacadeFactory(host)
        display_facade = factory.create_display_facade()
        chameleon_board = host.chameleon

        chameleon_board.setup_and_reset(self.outputdir)
        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(
                    host, 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 %r',
                         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:
                    chameleon_port.wait_video_input_stable()
                    if test_mirrored:
                        # Wait for resolution change to make sure the resolution
                        # is stable before moving on. This is to deal with the
                        # case where DUT may respond slowly after the noise.
                        # If the resolution doesn't change, then we are
                        # confident that it is stable. Otherwise, a slow
                        # response is caught.
                        r = display_facade.get_internal_resolution()
                        utils.wait_for_value_changed(
                                display_facade.get_internal_resolution,
                                old_value=r)

                    err = screen_test.check_external_display_connected(
                            expected_connector)

                    if not err:
                        err = screen_test.test_screen_with_image(
                                resolution, test_mirrored)
                    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)))
