# 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 is a server side to enable HDCP and verify screen."""

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_HDCPScreen(test.test):
    """Server side test to enable HDCP and verify screen.

    This test forces CrOS to enable HDCP and compares screens between CrOS
    and Chameleon.
    """
    version = 1

    TEST_CONFIGS = [
        # (enable_chameleon, request_cros, expected_cros_state,
        #  expected_chameleon_state)
        (True, 'Desired', 'Enabled', True),
        (False, 'Desired', 'Desired', False),
        # TODO: Investigate the case below which was disabled as it failed.
        # Check http://crbug.com/447493
        #(True, 'Undesired', 'Undesired', False),
        (False, 'Undesired', 'Undesired', False),
    ]

    DURATION_UNPLUG_FOR_HDCP = 1
    TIMEOUT_HDCP_SWITCH = 10

    def run_once(self, host, test_mirrored=False):
        if host.get_architecture() != 'arm':
            raise error.TestNAError('HDCP is not supported on a non-ARM device')

        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 = []
        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)

            resolution = display_facade.get_external_resolution()
            logging.info('Detected resolution on CrOS: %r', resolution)

            original_cros_state = display_facade.get_content_protection()
            was_chameleon_enabled = (
                    chameleon_port.is_content_protection_enabled())
            try:
                for (enable_chameleon, request_cros, expected_cros_state,
                     expected_chameleon_state) in self.TEST_CONFIGS:
                    # Do unplug and plug to emulate switching to a different
                    # display with a different content protection state.
                    chameleon_port.unplug()
                    logging.info('Set Chameleon HDCP: %r', enable_chameleon)
                    chameleon_port.set_content_protection(enable_chameleon)
                    time.sleep(self.DURATION_UNPLUG_FOR_HDCP)
                    chameleon_port.plug()
                    chameleon_port.wait_video_input_stable()

                    logging.info('Request CrOS HDCP: %s', request_cros)
                    display_facade.set_content_protection(request_cros)

                    state = utils.wait_for_value(
                            display_facade.get_content_protection, 'Enabled',
                            timeout_sec=self.TIMEOUT_HDCP_SWITCH)
                    logging.info('Got CrOS state: %s', state)
                    if state != expected_cros_state:
                        error_message = ('Failed to enable HDCP, state: %r' %
                                         state)
                        logging.error(error_message)
                        errors.append(error_message)

                    encrypted = chameleon_port.is_video_input_encrypted()
                    logging.info('Got Chameleon state: %r', encrypted)
                    if encrypted != expected_chameleon_state:
                        error_message = ('Chameleon found HDCP in wrong state: '
                                         'expected %r but got %r' %
                                         (expected_chameleon_state, encrypted))
                        logging.error(error_message)
                        errors.append(error_message)

                    logging.info('Test screen under HDCP %s...',
                                 'enabled' if encrypted else 'disabled')
                    screen_test.test_screen_with_image(
                            resolution, test_mirrored, errors)
            finally:
                display_facade.set_content_protection(original_cros_state)
                chameleon_port.set_content_protection(was_chameleon_enabled)

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