# -*- coding: utf-8 -*-
#
# Copyright (c) 2010 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.


# DESCRIPTION :
#
# Intended for use during manufacturing to validate that all keyboard
# keys function properly.  This program will display a keyboard image
# and keys will be highlighted as they are pressed and released.
# After the first key is hit, a countdown will begin.  If not all keys
# are used in time, the test will fail.


import cairo
import gobject
import gtk
import logging
import time
import os
import sys
import utils

import re
import subprocess

from gtk import gdk

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import factory_setup_modules
from cros.factory.test import factory
from cros.factory.test import ui as ful

# The keycodes from the GTK keyboard event have a +8 offset
# from the real one, hence the constant here
_GTK_KB_KEYCODE_OFFSET = 8

# GTK keycode for left Ctrl, Alt and Shift.
_LCTRL = 37
_LALT = 64
_LSHIFT = 50

# GTK state mask for key combination.
_MOD_MASK = gtk.gdk.CONTROL_MASK | gtk.gdk.MOD1_MASK | gtk.gdk.SHIFT_MASK

def GenerateKeycodeBinding(old_bindings):
    '''Offsets the bindings keycodes for GTK.'''
    key_to_geom = {}
    for item in old_bindings.items():
        key_to_geom[item[0] + _GTK_KB_KEYCODE_OFFSET] = (
                item[1] if isinstance(item[1], list) else [item[1],])
    return key_to_geom

class KeyboardTest:
    '''Keyboard test.

    Args:
      kbd_image: Keyboard image file
      binding: Keyboard binding file
      scale: image scaling factor
      accept_combi_key: (bool) True to accept combination key.
    '''

    def __init__(self, kbd_image, bindings, scale, accept_combi_key):
        self._kbd_image = kbd_image
        self._bindings = bindings
        self._scale = scale
        self._pressed_keys = set()
        self._deadline = None
        self.successful_keys = set()
        self._accept_combi_key = accept_combi_key

    def calc_missing_string(self):
        missing_keys = sorted((gdk.keyval_name(k) or '<0x%x>' % k)for k in
                              set(self._bindings) - self.successful_keys)
        if not missing_keys:
            return ''
        return ('Missing following keys\n' +
                '没有侦测到下列按键，键盘可能故障，请检修: %s' %
                ', '.join(missing_keys))

    def timer_event(self, countdown_label):
        if not self._deadline:   # Ignore timer with no countdown in progress.
            return True
        time_remaining = max(0, self._deadline - time.time())
        if time_remaining == 0:
            factory.log('deadline reached')
            gtk.main_quit()
        countdown_label.set_text('%d' % time_remaining)
        countdown_label.queue_draw()
        return True

    def expose_event(self, widget, event):
        context = widget.window.cairo_create()

        # Show keyboard image as the background.
        context.scale(self._scale, self._scale)
        context.set_source_surface(self._kbd_image, 0, 0)
        context.paint()

        for key in self.successful_keys:
            for coords in self._bindings[key]:
                context.rectangle(*coords)
                context.set_source_rgba(*ful.RGBA_GREEN_OVERLAY)
                context.fill()
        for key in self._pressed_keys:
            for coords in self._bindings[key]:
                context.rectangle(*coords)
                context.set_source_rgba(*ful.RGBA_YELLOW_OVERLAY)
                context.fill()

        return True

    def get_combined_keycode(self, event):
        '''Gets combined keycode.

        If Ctrl/Alt/Shift is also presented in key event, returns
        hardware_keycode + offset:
          Shift: 256
          Ctrl: 1024
          Alt: 2048

        Args:
          event: GTK event.

        Returns:
          Combined keycode explained above.
        '''
        return event.hardware_keycode + ((event.state & _MOD_MASK) << 8)

    def process_combi_key_press_event(self, event):
        '''Processes key-press event with combination key.

        Args:
          event: GTK event.

        Returns:
          (accept, keycode):
            accept == True if the key is in _bindings.
            keycode: combined keycode. Refer get_combined_keycode().
        '''
        keycode = self.get_combined_keycode(event)
        if keycode in self._bindings:
            # Known issue: if you press left Ctrl then "New Tab (Ctrl-T)", and
            # then release them, the left Ctrl will be discarded unexpectedly.
            # However, as it only hapeends when an operator sweeps keyboard
            # and presses left Ctrl first then "New Tab", which is rare. And
            # if it happends, operator can hit left Ctrl again to fix the
            # issue. So I will leave the issue open until we found a nice fix.
            if event.state & gtk.gdk.CONTROL_MASK:
                self._pressed_keys.discard(_LCTRL)
            if event.state & gtk.gdk.MOD1_MASK:
                self._pressed_keys.discard(_LALT)
            if event.state & gtk.gdk.SHIFT_MASK:
                self._pressed_keys.discard(_LSHIFT)
        elif event.hardware_keycode in self._bindings:
            # For those unbinded key combinations, treat them as only
            # base keys are pressed.
            keycode = event.hardware_keycode
        else:
            return False, 0
        return True, keycode

    def process_simple_key_press_event(self, event):
        '''Processes key-press event regardless key combination.

        Args:
          event: GTK event.

        Returns:
          (accept, keycode):
            accept == True if the key is in _bindings.
            keycode: hardware_keycode.
        '''
        keycode = event.hardware_keycode
        return keycode in self._bindings, keycode

    def key_press_event(self, widget, event):
        accept = False
        if self._accept_combi_key:
            accept, keycode = self.process_combi_key_press_event(event)
        else:
            accept, keycode = self.process_simple_key_press_event(event)
        if not accept:
            factory.log('key (0x%x) ignored because not in bindings'
                        % event.keyval)
            return True

        self._pressed_keys.add(keycode)
        widget.queue_draw()

        # The first keypress starts test countdown.
        if self._deadline is None:
            self._deadline = int(time.time()) + ful.FAIL_TIMEOUT

        return True

    def key_release_event(self, widget, event):
        hardware_keycode_check = True
        if self._accept_combi_key:
            keycode = self.get_combined_keycode(event)
            # If combined keycode is not pressed before, fall back to check
            # hardware_keycode instead.
            hardware_keycode_check = keycode not in self._pressed_keys
        if hardware_keycode_check:
            keycode = event.hardware_keycode
            if keycode not in self._pressed_keys:
                # Ignore releases for keys not previously accepted as pressed.
                return False
        self._pressed_keys.remove(keycode)
        self.successful_keys.add(keycode)
        widget.queue_draw()
        if not self.calc_missing_string():
            factory.log('completed successfully')
            gtk.main_quit()
        return True

    def register_callbacks(self, window):
        window.connect('key-press-event', self.key_press_event)
        window.connect('key-release-event', self.key_release_event)
        window.add_events(gdk.KEY_PRESS_MASK | gdk.KEY_RELEASE_MASK)


class factory_Keyboard(test.test):
    version = 1
    preserve_srcdir = True

    def get_layout_from_vpd(self):
       """ vpd should contain
          "initial_locale"="en-US"
          "keyboard_layout"="xkb:us::eng"
       or similar. """
       cmd = 'vpd -l | grep initial_locale | cut -f4 -d\'"\''
       layout = utils.system_output(cmd).strip()
       if layout != '':
           return layout
       return None

    def run_once(self, layout=None, combi_key=False, config_dir=''):
        '''

        Args:
          layout: use specified layout other than derived from VPD.
          combi_key: True to handle key combination.
          config_dir: specify directory to read keyboard image and binding
             from. If unspeified, read from default directory.
        '''

        factory.log('%s run_once' % self.__class__)

        os.chdir(self.srcdir)

        # Autodetect from VPD.
        if not layout:
            layout = self.get_layout_from_vpd()
        # Default to United States.
        if not layout:
            layout = 'en-US'

        factory.log("Using keyboard layout %s" % layout)
        layout_filename = os.path.join(config_dir, '%s.png' % layout)
        try:
            kbd_image = cairo.ImageSurface.create_from_png(layout_filename)
            image_size = (kbd_image.get_width(), kbd_image.get_height())
        except cairo.Error as e:
            raise error.TestNAError('Error while opening %s: %s' %
                                    (layout_filename, e.message))

        bindings_filename = os.path.join(config_dir, '%s.bindings' % layout)
        try:
            with open(bindings_filename, 'r') as file:
                bindings = eval(file.read())
                bindings = GenerateKeycodeBinding(bindings)
        except IOError as e:
            raise error.TestNAError('Error while opening %s: %s [Errno %d]' %
                                    (e.filename, e.strerror, e.errno))

        scale = ful.calc_scale(*image_size)

        test = KeyboardTest(kbd_image, bindings, scale, combi_key)

        scaled_image_size = (image_size[0] * scale, image_size[1] * scale)

        drawing_area = gtk.DrawingArea()
        drawing_area.set_size_request(*scaled_image_size)
        drawing_area.connect('expose_event', test.expose_event)
        drawing_area.add_events(gdk.EXPOSURE_MASK)

        countdown_widget, countdown_label = ful.make_countdown_widget()
        gobject.timeout_add(1000, test.timer_event, countdown_label)

        test_widget = gtk.VBox()
        test_widget.set_spacing(20)
        test_widget.pack_start(drawing_area, False, False)
        test_widget.pack_start(countdown_widget, False, False)

        ful.run_test_widget(self.job, test_widget,
            window_registration_callback=test.register_callbacks)

        missing = test.calc_missing_string()
        if missing:
            raise error.TestFail(missing)

        factory.log('%s run_once finished' % self.__class__)
