# Lint as: python2, python3
# Copyright 2017 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 module provides functions to record input events."""

from __future__ import division
from __future__ import print_function

import logging
import re
import select
import subprocess
import threading
import time

from autotest_lib.client.bin.input.linux_input import\
    EV_MSC, EV_SYN, MSC_SCAN, SYN_REPORT


# Define extra misc events below as they are not defined in linux_input.
MSC_SCAN_BTN_LEFT = 90001
MSC_SCAN_BTN_RIGHT = 90002
MSC_SCAN_BTN_MIDDLE = 90003


class InputEventRecorderError(Exception):
    """An exception class for input_event_recorder module."""
    pass


class Event(object):
    """An event class based on evtest constructed from an evtest event.

    An ordinary event looks like:
    Event: time 133082.748019, type 3 (EV_ABS), code 0 (ABS_X), value 316

    A SYN_REPORT event looks like:
    Event: time 10788.289613, -------------- SYN_REPORT ------------

    """

    def __init__(self, type=0, code=0, value=0):
        """Construction of an input event.

        @param type: the event type
        @param code: the event code
        @param value: the event value

        """
        self.type = type
        self.code = code
        self.value= value


    @staticmethod
    def from_string(ev_string):
        """Convert an event string to an event object.

        @param ev_string: an event string.

        @returns: an event object if the event string conforms to
                  event pattern format. None otherwise.

        """
        # Get the pattern of an ordinary event
        ev_pattern_time = r'Event:\s*time\s*(\d+\.\d+)'
        ev_pattern_type = r'type\s*(\d+)\s*\(\w+\)'
        ev_pattern_code = r'code\s*(\d+)\s*\(\w+\)'
        ev_pattern_value = r'value\s*(-?\d+)'
        ev_sep = r',\s*'
        ev_pattern_str = ev_sep.join([ev_pattern_time,
                                      ev_pattern_type,
                                      ev_pattern_code,
                                      ev_pattern_value])
        ev_pattern = re.compile(ev_pattern_str, re.I)

        # Get the pattern of the SYN_REPORT event
        ev_pattern_type_SYN_REPORT = r'-+\s*SYN_REPORT\s-+'
        ev_pattern_SYN_REPORT_str = ev_sep.join([ev_pattern_time,
                                                 ev_pattern_type_SYN_REPORT])
        ev_pattern_SYN_REPORT = re.compile(ev_pattern_SYN_REPORT_str, re.I)

        # Check if it is a SYN event.
        result = ev_pattern_SYN_REPORT.search(ev_string)
        if result:
            return Event(EV_SYN, SYN_REPORT, 0)
        else:
            # Check if it is a regular event.
            result = ev_pattern.search(ev_string)
            if result:
                ev_type = int(result.group(2))
                ev_code = int(result.group(3))
                ev_value = int(result.group(4))
                return Event(ev_type, ev_code, ev_value)
            else:
                return None


    def is_syn(self):
        """Determine if the event is a SYN report event.

        @returns: True if it is a SYN report event. False otherwise.

        """
        return self.type == EV_SYN and self.code == SYN_REPORT


    def value_tuple(self):
        """A tuple of the event type, code, and value.

        @returns: the tuple of the event type, code, and value.

        """
        return (self.type, self.code, self.value)


    def __eq__(self, other):
        """determine if two events are equal.

        @param line: an event string line.

        @returns: True if two events are equal. False otherwise.

        """
        return (self.type == other.type and
                self.code == other.code and
                self.value == other.value)


    def __str__(self):
        """A string representation of the event.

        @returns: a string representation of the event.

        """
        return '%d %d %d' % (self.type, self.code, self.value)


class InputEventRecorder(object):
    """An input event recorder.

    Refer to recording_example() below about how to record input events.

    """

    INPUT_DEVICE_INFO_FILE = '/proc/bus/input/devices'
    SELECT_TIMEOUT_SECS = 1

    def __init__(self, device_name, uniq):
        """Construction of input event recorder.

        @param device_name: the device name of the input device node to record.
        @param uniq: Unique address of input device (None if not used)

        """
        self.device_name = device_name
        self.uniq = uniq
        self.device_node = self.get_device_node_by_name(device_name, uniq)
        if self.device_node is None:
            err_msg = 'Failed to find the device node of %s' % device_name
            raise InputEventRecorderError(err_msg)
        self._recording_thread = None
        self._stop_recording_thread_event = threading.Event()
        self.tmp_file = '/tmp/evtest.dat'
        self.events = []


    def get_device_node_by_name(self, device_name, uniq):
        """Get the input device node by name.

        Example of a RN-42 emulated mouse device information looks like

        I: Bus=0005 Vendor=0000 Product=0000 Version=0000
        N: Name="RNBT-A96F"
        P: Phys=6c:29:95:1a:b8:18
        S: Sysfs=/devices/pci0000:00/0000:00:14.0/usb1/1-8/1-8:1.0/bluetooth/hci0/hci0:512:29/0005:0000:0000.0004/input/input15
        U: Uniq=00:06:66:75:a9:6f
        H: Handlers=event12
        B: PROP=0
        B: EV=17
        B: KEY=70000 0 0 0 0
        B: REL=103
        B: MSC=10

        Each group of input devices is separated by an empty line.

        @param device_name: the device name of the target input device node.
        @param uniq: Unique address of the device. None if unused.

        @returns: the corresponding device node of the device.

        """
        device_node = None
        device_found = None
        event_number = None
        uniq_found = None
        uniq = uniq.lower() if uniq else None

        entry_pattern = re.compile('^[A-Z]: ')
        device_pattern = re.compile('N: Name=.*%s' % device_name, re.I)
        event_number_pattern = re.compile('H: Handlers=.*event(\d*)', re.I)
        uniq_pattern = re.compile('U: Uniq=([a-zA-Z0-9:]+)')

        with open(self.INPUT_DEVICE_INFO_FILE) as info:
            for line in info:
                line = line.rstrip('\n')

                if not entry_pattern.search(line):
                    device_found = None
                    event_number = None
                    uniq_found = None
                elif device_found:
                    # Check if this is an event line
                    find_event = event_number_pattern.search(line)
                    if find_event:
                        event_number = int(find_event.group(1))

                    # Check if this a uniq line
                    find_uniq = uniq_pattern.search(line)
                    if find_uniq:
                        uniq_found = find_uniq.group(1).lower()

                    # If uniq matches expectations, we found the device node
                    if event_number and (not uniq or uniq_found == uniq):
                        device_node = '/dev/input/event%d' % event_number
                        break

                else:
                    device_found = device_pattern.search(line)

        return device_node


    def record(self):
        """Record input events."""
        logging.info('Recording input events of %s.', self.device_node)
        cmd = 'evtest %s' % self.device_node
        recorder = subprocess.Popen(cmd, stdout=subprocess.PIPE,
                                          shell=True)
        with open(self.tmp_file, 'w') as output_f:
            while True:
                read_list, _, _ = select.select(
                        [recorder.stdout], [], [], 1)
                if read_list:
                    line = recorder.stdout.readline()
                    output_f.write(line)
                    ev = Event.from_string(line)
                    if ev:
                        self.events.append(ev.value_tuple())
                elif self._stop_recording_thread_event.is_set():
                    self._stop_recording_thread_event.clear()
                    break

        recorder.terminate()


    def start(self):
        """Start the recording thread."""
        logging.info('Start recording thread.')
        self._recording_thread = threading.Thread(target=self.record)
        self._recording_thread.start()


    def stop(self):
        """Stop the recording thread."""
        logging.info('Stop recording thread.')
        self._stop_recording_thread_event.set()
        self._recording_thread.join()


    def clear_events(self):
        """Clear the event list."""
        self.events = []


    def get_events(self):
        """Get the event list.

        @returns: the event list.
        """
        return self.events


SYN_EVENT = Event(EV_SYN, SYN_REPORT, 0)
MSC_SCAN_BTN_EVENT = {'LEFT': Event(EV_MSC, MSC_SCAN, MSC_SCAN_BTN_LEFT),
                      'RIGHT': Event(EV_MSC, MSC_SCAN, MSC_SCAN_BTN_RIGHT),
                      'MIDDLE': Event(EV_MSC, MSC_SCAN, MSC_SCAN_BTN_MIDDLE)}


def recording_example():
    """Example code for capturing input events on a Samus.

    For a quick swipe, it outputs events in numeric format:

    (3, 57, 9)
    (3, 53, 641)
    (3, 54, 268)
    (3, 58, 60)
    (3, 48, 88)
    (1, 330, 1)
    (1, 325, 1)
    (3, 0, 641)
    (3, 1, 268)
    (3, 24, 60)
    (0, 0, 0)
    (3, 53, 595)
    (3, 54, 288)
    (3, 0, 595)
    (3, 1, 288)
    (0, 0, 0)
    (3, 57, -1)
    (1, 330, 0)
    (1, 325, 0)
    (3, 24, 0)
    (0, 0, 0)

    The above events in corresponding evtest text format are:

    Event: time .782950, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value 9
    Event: time .782950, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 641
    Event: time .782950, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 268
    Event: time .782950, type 3 (EV_ABS), code 58 (ABS_MT_PRESSURE), value 60
    Event: time .782950, type 3 (EV_ABS), code 59 (?), value 0
    Event: time .782950, type 3 (EV_ABS), code 48 (ABS_MT_TOUCH_MAJOR), value 88
    Event: time .782950, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
    Event: time .782950, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 1
    Event: time .782950, type 3 (EV_ABS), code 0 (ABS_X), value 641
    Event: time .782950, type 3 (EV_ABS), code 1 (ABS_Y), value 268
    Event: time .782950, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 60
    Event: time .782950, -------------- SYN_REPORT ------------
    Event: time .798273, type 3 (EV_ABS), code 53 (ABS_MT_POSITION_X), value 595
    Event: time .798273, type 3 (EV_ABS), code 54 (ABS_MT_POSITION_Y), value 288
    Event: time .798273, type 3 (EV_ABS), code 0 (ABS_X), value 595
    Event: time .798273, type 3 (EV_ABS), code 1 (ABS_Y), value 288
    Event: time .798273, -------------- SYN_REPORT ------------
    Event: time .821437, type 3 (EV_ABS), code 57 (ABS_MT_TRACKING_ID), value -1
    Event: time .821437, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
    Event: time .821437, type 1 (EV_KEY), code 325 (BTN_TOOL_FINGER), value 0
    Event: time .821437, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
    Event: time .821437, -------------- SYN_REPORT ------------
    """
    device_name = 'Atmel maXTouch Touchpad'
    recorder = InputEventRecorder(device_name)
    print('Samus touchpad device name:', recorder.device_name)
    print('Samus touchpad device node:', recorder.device_node)
    print('Please make gestures on the touchpad for up to 5 seconds.')
    recorder.clear_events()
    recorder.start()
    time.sleep(5)
    recorder.stop()
    for e in recorder.get_events():
        print(e)


if __name__ == '__main__':
    recording_example()
