# Lint as: python2, python3
# Copyright 2014 The ChromiumOS Authors
# 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 stressing DUT by switching Chameleon EDID."""

import glob
import logging
import os

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.client.cros.chameleon import edid
from autotest_lib.server import test
from autotest_lib.server.cros.multimedia import remote_facade_factory


class display_EdidStress(test.test):
    """Server side external display test.

    This test switches Chameleon EDID from among a large pool of EDIDs, tests
    DUT recognizes the emulated monitor and emits the correct video signal to
    Chameleon.
    """
    version = 1

    _EDID_TYPES = {'HDMI': {'HDMI', 'MHL', 'DVI'},
                   'DP': {'DP'},
                   'VGA': {'VGA'}}

    def run_once(self, host, edid_set):

        def _get_edid_type(s):
            i = s.rfind('_') + 1
            j = len(s) - len('.txt')
            return s[i:j].upper()

        edid_path = os.path.join(self.bindir, 'test_data', 'edids',
                                 edid_set, '*')

        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)
        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())

            connector = chameleon_port.get_connector_type()
            supported_types = self._EDID_TYPES[connector]

            failed_edids = []
            for filepath in glob.glob(edid_path):
                filename = os.path.basename(filepath)
                edid_type = _get_edid_type(filename)
                if edid_type not in supported_types:
                    logging.info('Skip EDID: %s...', filename)
                    continue

                logging.info('Use EDID: %s...', filename)
                try:
                    with chameleon_port.use_edid(
                            edid.Edid.from_file(filepath, skip_verify=True)):
                        resolution = utils.wait_for_value_changed(
                                display_facade.get_external_resolution,
                                old_value=None)
                        if resolution is None:
                            raise error.TestFail('No external display detected on DUT')
                        if screen_test.test_resolution(resolution):
                            raise error.TestFail('Resolution test failed')
                except (error.TestFail) as e:
                    logging.warning(e)
                    logging.error('EDID not supported: %s', filename)
                    failed_edids.append(filename)

            if failed_edids:
                message = ('Total %d EDIDs not supported: ' % len(failed_edids)
                           + ', '.join(failed_edids))
                logging.error(message)
                raise error.TestFail(message)
