# Copyright (c) 2011 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.

''' A module verifying whether X events satisfy specified criteria '''

import logging
import time
import utils

import Xevent

from operator import le, ge, eq, lt, gt, ne, and_
from trackpad_util import read_trackpad_test_conf


class Xcheck:
    ''' Check whether X events observe test criteria '''
    RESULT_STR = {True : 'Pass', False : 'Fail'}

    def __init__(self, dev, conf_path):
        self.dev = dev
        self.conf_path = conf_path
        self.xbutton = Xevent.XButton()
        self.button_labels = self.xbutton.get_supported_buttons()
        # Create a dictionary to look up button label
        #        e.g., {1: 'Button Left', ...}
        self.button_dict = dict(map(lambda b:
                                    (self.xbutton.get_value(b), b),
                                    self.button_labels))
        self._get_boot_time()
        self.xevent = Xevent.XEvent(self.xbutton)
        self.op_dict = {'>=': ge, '<=': le, '==': eq, '=': eq, '>': gt,
                        '<': lt, '!=': ne, '~=': ne, 'not': ne, 'is not': ne}

    def _get_boot_time(self):
        ''' Get the system boot up time

        Boot time can be used to convert the elapsed time since booting up
        to that since Epoch.
        '''
        stat_cmd = 'cat /proc/stat'
        stat = utils.system_output(stat_cmd)
        boot_time_tuple = tuple(int(line.split()[1])
                                for line in stat.splitlines()
                                if line.startswith('btime'))
        if len(boot_time_tuple) == 0:
            raise error.TestError('Fail to extract boot time by "%s"' %
                                  stat_cmd)
        self.boot_time = boot_time_tuple[0]

    def _set_flags(self):
        ''' Set all flags to True before invoking check function '''
        self.motion_flag = True
        self.button_flag = True
        self.seq_flag = True
        self.delay_flag = True

    def _get_result(self):
        ''' Get the final result from various check flags '''
        flags = (self.motion_flag, self.button_flag, self.seq_flag,
                 self.delay_flag)
        self.result = flags[0] if len(flags) == 1 else reduce(and_, flags)
        logging.info('    --> Result: %s' % Xcheck.RESULT_STR[self.result])

    def _compare(self, ops):
        ''' Compare function generator

        Generate a function to compare two sequences using the specified
        operators.
        '''
        return lambda seq1, seq2: reduce(and_, map(lambda op, s1, s2:
                                                   op(s1, s2), ops, seq1, seq2))

    def _motion_criteria(self, motion_crit):
        ''' Extract motion operator and value '''
        if motion_crit is None:
            return (None, None)
        motion_op = self.op_dict[motion_crit[1]]
        motion_value = motion_crit[2]
        return (motion_op, motion_value)

    def _button_criteria(self, button_labels, button_crit):
        ''' Create a list of button criteria
        This supports a list of button_labels in a more flexible way.

        For example,
        button_labels: ('Button Horiz Wheel Left', 'Button Horiz Wheel Right')
        button_crit: ('Button Wheel', '>=', 10)

        And assume that button_labels = (
            'Button Left', 'Button Middle', 'Button Right',
            'Button Wheel Up', 'Button Wheel Down',
            'Button Horiz Wheel Left', 'Button Horiz Wheel Right', ...)

        The result of this method is
        ops =    (eq, eq, eq, eq, eq, ge, ge, ...)
        values = ( 0,  0,  0,  0,  0, 10, 10, ...)
        '''
        len_button_labels = len(self.button_labels)
        ops = [eq] * len_button_labels
        values = [0] * len_button_labels
        if button_crit is not None:
            for button_label in button_labels:
                _, button_op, button_value = button_crit
                button_index = self.xbutton.get_index(button_label)
                ops[button_index] = self.op_dict[button_op]
                values[button_index] = button_value
        return (ops, values)

    def _insert_nop(self, nop_str):
        ''' Insert a 'NOP' fake event into the xevent_data

        NOP is not an X event. It is inserted to indicate the occurrence of
        related device events.
        '''
        if nop_str == 'Two Finger Touch':
            dev_event_time = self.dev.get_two_finger_touch_time_list()
        else:
            dev_event_time = self.dev.get_finger_time(nop_str)

        if dev_event_time is None:
            logging.warn('Cannot get time for %s.' % nop_str)
            return

        # Insert NOP event into xevent data
        begin_index = 0
        for devent_time in dev_event_time:
            for index, line in enumerate(self.xevent.xevent_data[begin_index:]):
                xevent_name = line[0]
                xevent_dict = line[1]
                if xevent_name == 'NOP':
                    continue
                xevent_time = float(xevent_dict.get('time', 0))
                if xevent_time > devent_time:
                    insert_index = begin_index + index
                    nop_data = ('NOP', nop_str, devent_time)
                    self.xevent.xevent_data.insert(insert_index, nop_data)
                    begin_index = insert_index + 1
                    break

    def _insert_nop_per_criteria(self, criteria_method):
        ''' Insert NOP based on criteria '''
        for c in criteria_method:
            if self.criteria.has_key(c):
                if c == 'wheel_speed':
                    # There are a couple of times of two-finger scrolling.
                    # Insert NOP between them in self.xevent_seq
                    self._insert_nop('Two Finger Touch')
                elif c == 'sequence':
                    crit_sequence = self.criteria[c]
                    # Insert NOP in self.xevent_seq if NOP is specified
                    # in sequence criteria.
                    # Example of crit_sequence below:
                    #     ('NOP', '1st Finger Lifted')
                    #     ('NOP', '2nd Finger Lifted')
                    for s in crit_sequence:
                        if s[0] == 'NOP':
                            self._insert_nop(s[1])

    def _extract_func_name(self):
        ''' Extract functionality name from the gesture file name '''
        return self.gesture_file_name.split('-')[self.func_name_pos]

    def _get_direction(self):
        ''' Get a specific direction from functionality name '''
        directions = ['up', 'down', 'left', 'right']
        file_name = self._extract_func_name()
        for d in directions:
            if d in file_name:
                return d
        return None

    def _get_general_direction(self):
        ''' Get a general direction from functionality name '''
        direction = self._get_direction()
        if direction is not None:
            return direction
        directions = ['vert', 'horiz', 'alldir']
        file_name = self._extract_func_name()
        for d in directions:
            if d in file_name:
                return d
        return None

    def _get_more_directions(self):
        ''' Get direction(s) from functionality name '''
        dir_dict = {'vert': ('up', 'down'),
                    'horiz': ('left', 'right'),
                    'alldir': ('up', 'down', 'left', 'right')}
        direction = self._get_direction()
        if direction is not None:
            return (direction,)
        file_name = self._extract_func_name()
        for d in dir_dict.keys():
            if d in file_name:
                return dir_dict[d]

    def _get_button_wheel_label_per_direction(self):
        ''' Use the specific direction in gesture file name to get
        correct button label.

        Extract the scroll direction ('up', 'down', 'left', or 'right')
        from the gesture file name. Use the scroll direction to derive
        the correct button label.
        E.g., for direction = 'up':
              'Button Wheel' in config file is replaced by 'Button Wheel Up'
        '''
        direction = self._get_direction()
        button_label = self.xbutton.wheel_label_dict[direction]
        return button_label

    def _get_button_wheel_labels_from_directions(self):
        ''' Use the direction(s) in gesture file name to get the corresponding
        button wheel label(s)
        '''
        directions = self._get_more_directions()
        button_labels = [self.xbutton.wheel_label_dict[d] for d in directions]
        return button_labels

    ''' _verify_xxx()
    Generic verification methods for various functionalities / areas
    '''

    def _verify_motion(self, crit_tot_movement):
        ''' Verify if the observed motions satisfy the criteria '''
        op, val = self._motion_criteria(crit_tot_movement)
        self.motion_flag = op(self.xevent.sum_move, val)
        logging.info('        Verify motion: (%s)' %
                     Xcheck.RESULT_STR[self.motion_flag])
        logging.info('              Total movement = %d' % self.xevent.sum_move)

    def _verify_button(self, crit_button):
        ''' Verify if the observed buttons satisfy the criteria

        Example of computing count_flag:
            compare =              (  eq,  ge,    eq, ...)
            xevent.count_buttons = (   0,   3,     0, ...)
            crit_count =           (   0,   1,     0, ...)
            result list =          [True, True, True, ...]
            count_flag =           True   (which is the AND of the result_list)
        '''
        if crit_button is None:
            crit_button_labels = None
        elif crit_button[0] == 'Button Wheel':
            crit_button_labels = self._get_button_wheel_labels_from_directions()
        else:
            crit_button_labels = (crit_button[0],)

        op, crit_count = self._button_criteria(crit_button_labels, crit_button)
        compare = self._compare(tuple(op))

        # Compare if all parsed button counts meet the criteria
        count_flag = compare(self.xevent.count_buttons, crit_count)

        # An X Button must end with a ButtonRelease
        state_flags = map(lambda s: s == 'ButtonRelease',
                          self.xevent.button_states)
        state_flag = reduce(and_, state_flags)

        self.button_flag = state_flag and count_flag

        logging.info('        Verify button: (%s)' %
                     Xcheck.RESULT_STR[self.button_flag])
        button_msg_details = '              %s %d times'
        count_flag = False
        for idx, b in enumerate(self.button_labels):
            if self.xevent.count_buttons[idx] > 0:
                logging.info(button_msg_details %
                             (b, self.xevent.count_buttons[idx]))
                count_flag = True
        if not count_flag:
            logging.info('              No Button events detected.')


    def _verify_select_delay(self, crit_delay):
        ''' Verify if the delay time satisfy the criteria

        The delay time is defined to be the time interval between the time
        the 2nd finger touching the trackpad and the time of the corresponding
        X Motion event.
        '''
        # Extract scroll direction, i.e., 'up' or 'down', from the file name
        # We do not support scrolling 'left' or 'right' at this time.
        pos = self.func_name_pos
        direction = self._get_direction()

        # Derive the device event playback time when the 2nd finger touches
        dev_event_time = self.dev.get_2nd_finger_touch_time(direction)

        # Derive the motion event time of the 2nd finger
        found_ButtonPress = False
        event_time = None
        for line in self.xevent.xevent_data:
            event_name = line[0]
            event_dict = line[1]
            if not found_ButtonPress and event_name == 'ButtonPress':
                found_ButtonPress = True
            elif found_ButtonPress and event_name == 'MotionNotify':
                event_time = float(event_dict['time'])
                break

        if dev_event_time is None or event_time is None:
            delay = 'Not found'
            self.delay_flag = False
        else:
            delay = (event_time - dev_event_time) * 0.001
            self.delay_flag = delay < crit_delay
        logging.info('        Verify delay: (%s)' %
                     Xcheck.RESULT_STR[self.delay_flag])
        logging.info('              Delay time = %s (criteria = %f)' %
                     (str(delay), crit_delay))

    def _verify_wheel_speed(self, crit_wheel_speed):
        ''' Verify if the observed button wheel speed satisfies the criteria

        xevent_seq for two-finger scrolling looks like:
            ('Motion', (0, ('Motion_x', 0), ('Motion_y', 0)))
            ('NOP', 'Two Finger Touch')
            ('Button Wheel Down', 62)
            ('Button Horiz Wheel Right', 1)
            ('Button Wheel Down', 65)
            ('Button Horiz Wheel Right', 1)
            ('Button Wheel Down', 32)
            ('Button Horiz Wheel Right', 1)
            ('Button Wheel Down', 35)
            ('Button Horiz Wheel Right', 2)
            ('Button Wheel Down', 15)
            ('NOP', 'Two Finger Touch')
            ('Button Wheel Down', 185)
            ('NOP', 'Two Finger Touch')
            ('Motion', (22.0, ('Motion_x', 11), ('Motion_y', 19)))
            ('Button Wheel Down', 68)
            ('Motion', (0, ('Motion_x', 0), ('Motion_y', 0)))

        Need to accumulate the button counts partitioned by NOP (two finger
        touching event). The Button Wheel event count derived in this way
        should satisfy the wheel speed criteria.
        '''

        # Aggregate button counts partitioned by 'NOP'
        button_count_list = []
        init_time = [None, None]
        rounds = 0
        for line in self.xevent.xevent_seq:
            event_name, event_count, event_time = line
            if event_name == 'NOP':
                button_count = self.xbutton.init_button_struct_with_time(0,
                               init_time)
                button_count_list.append(button_count)
                rounds += 1
            elif rounds > 0:
                if event_name.startswith('Button'):
                    button_value = self.xbutton.get_value(event_name)
                    count = button_count_list[rounds-1][button_value][0]
                    if count == 0:
                        button_count_list[rounds-1][button_value][1] = \
                                event_time
                    else:
                        button_count_list[rounds-1][button_value][1][1] = \
                                event_time[1]
                    # TODO(josephsih): It is hard to follow this code; It would
                    # be better if this used an associative array ['event']
                    # ['count'], dictionary or class instead of just [0] and
                    # [1].
                    button_count_list[rounds-1][button_value][0] += event_count

        speed = [0] * rounds
        # Calculate button wheel speed
        for i, button_count in enumerate(button_count_list):
            speed[i] = self.xbutton.init_button_struct(0)
            for k, v in button_count.iteritems():
                if v[0] > 0:
                    time_list = button_count[k][1]
                    time_interval = (time_list[1] - time_list[0]) / 1000.0
                    speed[i][k] = ((button_count[k][0] / time_interval)
                                   if time_interval != 0 else 1)

        # Verify if the target button satisfies wheel speed criteria
        button_label = self._get_button_wheel_label_per_direction()
        self.wheel_speed_flag = True
        if rounds <= 1:
            self.wheel_speed_flag = False
        else:
            target_button_value = self.xbutton.get_value(button_label)
            comp_op = self.op_dict[crit_wheel_speed[1]]
            multiplier = crit_wheel_speed[2]
            for r in range(1, rounds):
                if not comp_op(speed[r][target_button_value],
                               speed[r-1][target_button_value] * multiplier):
                    self.wheel_speed_flag = False
                    break

        prefix_space0 = ' ' * 8
        prefix_space1 = ' ' * 10
        prefix_space2 = ' ' * 14
        msg_title = prefix_space0 + 'Verify wheel speed: (%s)'
        msg_round = prefix_space1 + 'Round %d of two-finger scroll:'
        msg_speed = '{0:<25s}: {1:7.2f} times/sec ({2:4} times in [{3} {4}])'
        msg_details = prefix_space2 + msg_speed
        logging.info(msg_title % Xcheck.RESULT_STR[self.wheel_speed_flag])
        for i, button_count in enumerate(button_count_list):
            logging.info(msg_round % i)
            for k, v in button_count.iteritems():
                if v[0] > 0:
                    logging.info(msg_details.format(self.xbutton.get_label(k),
                                 speed[i][k], v[0], str(v[1][0]), str(v[1][1])))

    def _verify_select_sequence(self, crit_sequence):
        ''' Verify event sequence against criteria sequence

        For example, the following event_sequence matches crit_sequence.
        event_sequence: [('ButtonPress', 'Button Left'),
                         ('Motion', 68),
                         ('ButtonRelease', 'Button Left')]
        crit_sequence:  (('ButtonPress', 'Button Left'),
                         ('Motion', '>=', 20),
                         ('ButtonRelease', 'Button Left'))
        '''

        def _get_criteria(index, crit_sequence):
            if index >= len(crit_sequence):
                crit_e = ''
                crit_e_type = ''
            else:
                crit_e = crit_sequence[index]
                crit_e_type = crit_e[0]
                # Add Button Wheel direction
                # Support only 'up', 'down', 'left', 'right' at this time in
                # sequence criteria.
                # May support 'vert', 'horiz', and 'alldir' later if needed.
                if crit_e_type == 'Button Wheel':
                    crit_e_type = self._get_button_wheel_label_per_direction()
            return (crit_e, crit_e_type)

        op_le = self.op_dict['<=']
        axis_dict = {'left': 'x', 'right': 'x', 'up': 'y', 'down': 'y',
                     'vert': 'y', 'horiz': 'x', 'alldir': '', None: ''}
        self.seq_flag = True
        crit_move_ratio = self.criteria.get('move_ratio', 0)

        if '*' in crit_sequence:
            work_crit_sequence = list(crit_sequence)
            work_crit_sequence.reverse()
            work_xevent_seq = list(self.xevent.xevent_seq)
            work_xevent_seq.reverse()
        else:
            work_crit_sequence = crit_sequence
            work_xevent_seq = self.xevent.xevent_seq

        # Read some default parameters from config file
        max_motion_mixed = read_trackpad_test_conf('max_motion_mixed',
                                                   self.conf_path)
        max_button_wheel_mixed = read_trackpad_test_conf(
                                 'max_button_wheel_mixed', self.conf_path)

        index = -1
        crit_e_type = None
        keep_prev_crit = False
        for e in work_xevent_seq:
            e_type = e[0]
            e_value = e[1]
            fail_msg = None
            if crit_e_type != '*':
                if keep_prev_crit:
                    keep_prev_crit = False
                else:
                    index += 1
            (crit_e, crit_e_type) = _get_criteria(index, work_crit_sequence)

            # When there is no detected motion, skip the motion criteria if any
            # and get next criteria in the sequence.
            if (not e_type.startswith('Motion') and
                crit_e_type.startswith('Motion')):
                index += 1
                (crit_e, crit_e_type) = _get_criteria(index, work_crit_sequence)

            # Pass this event if the criteria is a wildcard
            if crit_e_type == '*':
                pass
            # Handle the situation that e_type not equal to crit_e_type
            elif not crit_e_type.startswith(e_type):
                keep_prev_crit = True
                if e_type.startswith('Motion'):
                    motion_val = e_value[0]
                    if motion_val > max_motion_mixed:
                        fail_msg = '%s (%d) is not allowed.'
                        fail_para = (e_type, motion_val)
                        break
                elif e_type.startswith('Button '):
                    if e_value > max_button_wheel_mixed:
                        fail_msg = '%s (%d) is not allowed'
                        fail_para = (e_type, e_value)
                        break
                else:
                    fail_msg = '%s (%s) is not allowed'
                    fail_para = (e_type, str(e_value))
                    break
            # Handle Motion event
            elif e_type.startswith('Motion'):
                motion_val = e_value[0]
                motion_x_val = e_value[1][1]
                motion_y_val = e_value[2][1]
                if crit_e_type.startswith('Motion'):
                    crit_e_op = crit_e[1]
                    crit_e_val = crit_e[2]
                    op = self.op_dict[crit_e_op]
                    if crit_e_type == 'Motion':
                        crit_check = op(motion_val, crit_e_val)
                        if not crit_check:
                            fail_msg = '%s %s does not satisfy %s. '
                            fail_para = (crit_e_type, str(e_value), str(crit_e))
                            break
                    elif crit_e_type == 'Motion_x_or_y':
                        axis = axis_dict[self._get_general_direction()]
                        motion_axis_dict = {'x': {'this':  motion_x_val,
                                                  'other': motion_y_val},
                                            'y': {'this':  motion_y_val,
                                                  'other': motion_x_val}}
                        motion_axis_val = motion_axis_dict[axis]['this']
                        motion_other_val = motion_axis_dict[axis]['other']

                        check_this_axis = op(motion_axis_val, crit_e_val)
                        # If the criteria requests that one axis move more
                        # than a threshold value, the other axis should move
                        # much less. This is to confirm that the movement is
                        # in the right direction.
                        other_axis_cond = crit_e_op == '>=' or crit_e_op == '>'
                        bound_other_axis = motion_axis_val * crit_move_ratio
                        check_other_axis = (not other_axis_cond or
                                    op_le(motion_other_val, bound_other_axis))
                        crit_check = check_this_axis and check_other_axis
                        if not crit_check:
                            fail_msg = ('%s %s does not satisfy %s. '
                                        'Check motion for this axis = %s. '
                                        'Check motion for the other axis = %s')
                            fail_para = (crit_e_type, str(e_value), str(crit_e),
                                         check_this_axis, check_other_axis)
                            break
                    else:
                        fail_msg = '%s does not conform to the format.'
                        fail_para = crit_e_type
                        break
                else:
                    # No motion allowed
                    if e_value > 0:
                        fail_msg = 'Motion %d is not allowed.'
                        fail_para = e_value
                        break
            # Handle button events for Button Left/Middle/Right
            elif (e_type == crit_e_type == 'ButtonPress' or
                  e_type == crit_e_type == 'ButtonRelease'):
                # Check if the button label matches criteria
                if e_value != crit_e[1]:
                    fail_msg = 'Button %s does not match %s.'
                    fail_para = (e_value, crit_e[1])
                    break
            elif e_type == crit_e_type == 'NOP':
                pass
            # Handle 'Button Wheel' and 'Button Horiz Wheel' scroll events
            elif e_type.startswith('Button ') and e_type == crit_e_type:
                op_str = crit_e[1]
                comp_op = self.op_dict[op_str]
                crit_button_count = crit_e[2]
                if not comp_op(e_value, crit_button_count):
                    fail_msg = '%s count %d does not satisfy "%s" %d.'
                    fail_para = (e_type, e_value, op_str, crit_button_count)
                    break
            else:
                fail_msg = 'Event %s does not match criteria %s.'
                fail_para = (e_type, crit_e_type)
                break

        # Check if the criteria has been fully matched
        if fail_msg is None and index < len(work_crit_sequence) - 1:
            # Pass if the rest of criteria are trivial ones such as
            #       'Motion <= ...'
            #       'Button Wheel <= ...'
            index += 1
            trivial_op_list = ['<', '<=']
            for i in range(index, len(work_crit_sequence)):
                (crit_e, crit_e_type) = _get_criteria(index, work_crit_sequence)
                if (crit_e_type.startswith('Motion') or
                    crit_e_type.startswith('Button ')):
                    crit_e_op = crit_e[1]
                    if crit_e_op not in trivial_op_list:
                        fail_msg = ('Some events are missing compared to the '
                                    'criteria: %s.')
                        fail_para = str(crit_sequence)
                        break

        if fail_msg is not None:
            self.seq_flag = False

        logging.info('        Verify select sequence: (%s)' %
                     Xcheck.RESULT_STR[self.seq_flag])
        logging.info('              Detected event sequence')
        for e in self.xevent.xevent_seq:
            logging.info('                      ' + str(e))
        if not self.seq_flag:
            logging.info('              ' + fail_msg % fail_para)

    def _verify_all_criteria(self):
        ''' A general verification method for all criteria

        This is the core method invoked for every functionality. What to check
        is based on the criteria specified for the functionality in the
        config file.
        '''
        # A dictionary mapping criterion to its verification method
        criteria_method = {'total_movement': self._verify_motion,
                           'button': self._verify_button,
                           'delay': self._verify_select_delay,
                           'wheel_speed': self._verify_wheel_speed,
                           'sequence': self._verify_select_sequence,
         }

        # Insert NOP based on criteria
        self._insert_nop_per_criteria(criteria_method)

        # Parse X button and motion events and aggregate the results.
        self.xevent.parse_button_and_motion()

        # Check those criteria specified in the config file.
        for c in criteria_method:
            if self.criteria.has_key(c):
                crit_item = self.criteria[c]
                criteria_method[c](crit_item)

        # AND all results of various criteria.
        self._get_result()

    def run(self, tp_func, tp_data,  xevent_str):
        ''' Parse the x events and invoke a proper check function

        Invoke the corresponding check function based on its functionality name.
        For example, tp_func.name == 'no_cursor_wobble' will result in the
        invocation of self._check_no_cursor_wobble()
        '''
        parse_result = self.xevent.parse_raw_string(xevent_str)
        self.gesture_file_name = tp_data.file_basename
        self.func_name_pos = 0 if tp_data.prefix is None else 1
        self.criteria = tp_func.criteria
        if parse_result:
            self._set_flags()
            self._verify_all_criteria()
            return self.result
        else:
            return False
