# 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 for extracting trackpad device file properties '''

import logging
import os

import constants
import trackpad_util

from autotest_lib.client.bin import utils
from autotest_lib.client.bin.input.linux_input import *
from autotest_lib.client.common_lib import error
from trackpad_util import read_trackpad_test_conf, get_trackpad_device_file


# Declare NOP as a instance containing NOP related constants
NOP = constants.NOP()


class TrackpadDevice:
    ''' Management of the trackpad device file

    It is used
    (1) to extract trackpad device file properties such as device event
        playback times, and
    (2) to play back the device packets. The device file is usually
        '/dev/input/event*'.
    '''
    playback_program_default = 'evemu-play'
    playback_program_emerged = '/usr/bin/evemu-play'
    DEVICE_TIME_FILE = '/tmp/time.out'

    def __init__(self):
        self._init_event_type_code()
        self._init_event_structure()
        self._set_dev_type_and_code()
        if self._get_trackpad_driver() == 'synaptics':
            self._ungrab_device()
        self.trackpad_device_file, msg = get_trackpad_device_file()
        if self.trackpad_device_file is None:
            raise error.TestError(msg)
        logging.info(msg)

        if os.path.isfile(self.playback_program_emerged):
            self.playback_program = self.playback_program_emerged
        else:
            self.playback_program = self.playback_program_default
        logging.info('Trackpad device playback program: %s' %
                     self.playback_program)

    def _init_event_type_code(self):
        ''' Initialize event type and code '''
        self.ev_format = ev_format = '%04x'

        # Event types
        self.EV_SYN = ev_format % EV_SYN
        self.EV_KEY = ev_format % EV_KEY
        self.EV_ABS = ev_format % EV_ABS

        # Event codes for synchronization event
        self.SYN_REPORT = ev_format % SYN_REPORT

        # Event codes for absolute axes
        self.ABS_MT_SLOT = ev_format % ABS_MT_SLOT
        self.ABS_MT_TRACKING_ID = ev_format % ABS_MT_TRACKING_ID

        # Event codes for keys and buttons
        self.BTN_MOUSE = ev_format % BTN_MOUSE
        self.BTN_TOUCH = ev_format % BTN_TOUCH
        self.BTN_TOOL_FINGER = ev_format % BTN_TOOL_FINGER
        self.BTN_TOOL_DOUBLETAP = ev_format % BTN_TOOL_DOUBLETAP
        self.BTN_TOOL_TRIPLETAP = ev_format % BTN_TOOL_TRIPLETAP
        self.BTN_TOOL_QUADTAP = ev_format % BTN_TOOL_QUADTAP

        # Event codes for keys and buttons
        self.ABS_X = ev_format % ABS_X
        self.ABS_Y = ev_format % ABS_Y
        self.ABS_PRESSURE = ev_format % ABS_PRESSURE
        self.ABS_MT_SLOT = ev_format % ABS_MT_SLOT
        self.ABS_MT_POSITION_X = ev_format % ABS_MT_POSITION_X
        self.ABS_MT_POSITION_Y = ev_format % ABS_MT_POSITION_Y
        self.ABS_MT_TRACKING_ID = ev_format % ABS_MT_TRACKING_ID
        self.ABS_MT_PRESSURE = ev_format % ABS_MT_PRESSURE

    def _init_event_structure(self):
        ev_type_code = '%s %s'
        ev_struct = '%s %s %d'
        self.finger_on = ev_struct % (self.EV_KEY, self.BTN_TOUCH, 1)
        self.finger_off = ev_struct % (self.EV_KEY, self.BTN_TOUCH, 0)
        self.mouse_click_press = ev_struct % (self.EV_KEY, self.BTN_MOUSE, 1)
        self.mouse_click_release = ev_struct % (self.EV_KEY, self.BTN_MOUSE, 0)
        self.one_finger_on = ev_struct % (self.EV_KEY, self.BTN_TOOL_FINGER, 1)
        self.one_finger_off = ev_struct % (self.EV_KEY, self.BTN_TOOL_FINGER, 0)
        self.two_fingers_on = ev_struct % (self.EV_KEY,
                                           self.BTN_TOOL_DOUBLETAP, 1)
        self.two_fingers_off = ev_struct % (self.EV_KEY,
                                            self.BTN_TOOL_DOUBLETAP, 0)
        self.three_fingers_on = ev_struct % (self.EV_KEY,
                                             self.BTN_TOOL_TRIPLETAP, 1)
        self.three_fingers_off = ev_struct % (self.EV_KEY,
                                              self.BTN_TOOL_TRIPLETAP, 0)
        self.four_fingers_on = ev_struct % (self.EV_KEY,
                                            self.BTN_TOOL_QUADTAP, 1)
        self.four_fingers_off = ev_struct % (self.EV_KEY,
                                             self.BTN_TOOL_QUADTAP, 0)
        self.tracking_id = ev_type_code % (self.EV_ABS, self.ABS_MT_TRACKING_ID)
        self.slot = ev_type_code % (self.EV_ABS, self.ABS_MT_SLOT)
        self.abs_mt_x = ev_type_code % (self.EV_ABS, self.ABS_MT_POSITION_X)
        self.abs_mt_y = ev_type_code % (self.EV_ABS, self.ABS_MT_POSITION_Y)
        self.abs_mt_z = ev_type_code % (self.EV_ABS, self.ABS_MT_PRESSURE)
        self.abs_x = ev_type_code % (self.EV_ABS, self.ABS_X)
        self.abs_y = ev_type_code % (self.EV_ABS, self.ABS_Y)
        self.abs_z = ev_type_code % (self.EV_ABS, self.ABS_PRESSURE)
        self.ev_syn = ev_type_code % (self.EV_SYN, self.SYN_REPORT)

    def _finger_i_on_MTB(self, i):
        ''' The i-th finger touches the trackpad in MTB protocol '''
        return '%s %s %d'  % (self.EV_ABS, self.ABS_MT_SLOT, i - 1)

    def _set_dev_type_and_code(self):
        ''' Set device code

        Device event types and codes are imported from linux_input.
        '''
        ev_code_x = self.ev_format % ABS_MT_POSITION_X
        ev_code_y = self.ev_format % ABS_MT_POSITION_Y
        self.ev_code_dict = {'left': (ev_code_x,),
                             'right': (ev_code_x,),
                             'up': (ev_code_y,),
                             'down': (ev_code_y,),
                             None: (ev_code_x, ev_code_y)}

        # MTA: not supported at this time

        # MTB: the default MT type to use
        self.second_finger_on_MTB = self._finger_i_on_MTB(2)
        self.finger_off_MTB = '%s %s -1' % (self.EV_ABS,
                                            self.ABS_MT_TRACKING_ID)

        finger_MTB = '{0} %s {1}'
        finger_on_MTB = finger_MTB.format(self.EV_KEY, 1)
        finger_off_MTB = finger_MTB.format(self.EV_KEY, 0)

        self.dev_event = {
            NOP.FINGER1_LANDED: finger_on_MTB  % self.BTN_TOOL_FINGER,
            NOP.FINGER1_LIFTED: finger_off_MTB % self.BTN_TOOL_FINGER,
            NOP.FINGER2_LANDED: finger_on_MTB  % self.BTN_TOOL_DOUBLETAP,
            NOP.FINGER2_LIFTED: finger_off_MTB % self.BTN_TOOL_DOUBLETAP,
            NOP.FINGER3_LANDED: finger_on_MTB  % self.BTN_TOOL_TRIPLETAP,
            NOP.FINGER3_LIFTED: finger_off_MTB % self.BTN_TOOL_TRIPLETAP,
            NOP.DEVICE_MOUSE_CLICK_PRESS: self.mouse_click_press,
            NOP.DEVICE_MOUSE_CLICK_RELEASE: self.mouse_click_release,
            NOP.FINGER_ON: self.finger_on,
            NOP.FINGER_OFF: self.finger_off,
            NOP.ONE_FINGER_ON: self.one_finger_on,
            NOP.TWO_FINGERS_ON: self.two_fingers_on,
            NOP.THREE_FINGERS_ON: self.three_fingers_on,
            NOP.FOUR_FINGERS_ON: self.four_fingers_on,
        }

    def _extract_playback_time(self, line):
        ''' Extract the actual event playback time from the line '''
        return int(float(line.split('playback ')[1]) * 1000)

    def find_all_event_time(self, ev_str):
        ''' Find the timestamps of all occurences of an event '''
        with open(TrackpadDevice.DEVICE_TIME_FILE) as f:
            time_file = f.read().splitlines()

        ev = self.dev_event[ev_str]
        time_list = []
        for line in time_file:
            if ev in line:
                time_list.append(self._extract_playback_time(line))
        return time_list

    def _find_event_time(self, ev_seq):
        ''' Match the events in ev_seq against the device time file, and
        return the timestamp of the first matched device events.
        '''
        ev_seq_len = len(ev_seq)
        if ev_seq_len == 0:
            return None

        with open(TrackpadDevice.DEVICE_TIME_FILE) as f:
            time_file = f.read().splitlines()

        ev = ev_seq.pop(0)
        for line in time_file:
            if ev in line:
                if len(ev_seq) == 0:
                    return self._extract_playback_time(line)
                ev = ev_seq.pop(0)
        return None

    def get_finger_time(self, ev_str):
        ''' Derive the device playback time of a specified event '''
        ev_seq_MTB = [self.dev_event[ev_str]]
        ev_time = self._find_event_time(ev_seq_MTB)
        return [ev_time] if ev_time is not None else []

    def get_2nd_finger_touch_time(self, direction):
        ''' Derive the device playback time when the 2nd finger touches '''
        ev_time = None
        # When the functionality is 'two_fingers_no_delay_2d' in config file,
        # check the ABS_MT_POSITION_X or ABS_MT_POSITION_Y event time.
        # Use the timestamp which occurs earlier.
        for ev_code in self.ev_code_dict[direction]:
            motion_code = '%s %s' % (self.EV_ABS, ev_code)
            ev_seq_MTB = [self.second_finger_on_MTB, motion_code]
            new_ev_time = self._find_event_time(ev_seq_MTB)
            ev_time = new_ev_time if ev_time is None else min(ev_time,
                                                              new_ev_time)
        return ev_time

    def get_2nd_finger_lifted_time(self):
        ''' Derive the device playback time when the 2nd finger is lifted '''
        ev_seq_MTB = [self.second_finger_on_MTB, self.finger_off_MTB]
        return self._find_event_time(ev_seq_MTB)

    def get_two_finger_touch_time_list(self):
        ''' Derive all device playback times when two fingers touch the pad '''
        with open(TrackpadDevice.DEVICE_TIME_FILE) as f:
            time_file = f.read().splitlines()

        ev = self.dev_event[NOP.FINGER2_LANDED]
        touch_time_list = []
        for line in time_file:
            if ev in line:
                touch_time_list.append(self._extract_playback_time(line))
        return touch_time_list

    def _get_trackpad_driver(self):
        ''' Query which trackpad driver is used in xorg '''
        trackpad_drivers = read_trackpad_test_conf('trackpad_drivers', '.')
        xorg_log = read_trackpad_test_conf('xorg_log', '.')

        try:
            f = open(xorg_log)
        except IOError:
            raise error.TestError('Xorg log file %s does not exist.' % xorg_log)
        log_lines = f.read().splitlines()
        f.close()

        for line in log_lines:
            if 'LoadModule' in line:
                for driver in trackpad_drivers:
                    if driver in line:
                        logging.info('Trackpad driver "%s" is found.' % driver)
                        self.trackpad_driver = driver
                        return self.trackpad_driver
        raise error.TestError('Cannot find driver in %s.' %
                              str(trackpad_drivers))

    def _ungrab_device(self):
        ''' Ungrab the device if the driver is synaptics and is grabbed '''
        self.grab_value = -1
        display_environ = trackpad_util.Display().get_environ()
        synclient_list_cmd = ' '.join([display_environ, 'synclient -l'])
        self.grab_device = ' '.join([display_environ,
                                     'synclient GrabEventDevice=%d'])
        synclient_settings = utils.system_output(synclient_list_cmd)
        for line in synclient_settings.splitlines():
            if line.lstrip().startswith('GrabEventDevice'):
                self.grab_value = int(line.split('=')[1].strip())
                break
        logging.info('GrabEventDevice=%d.' % self.grab_value)
        if self.grab_value == -1:
            err_msg = 'Cannot find GrabEventDevice setting in "%s".'
            raise error.TestError(err_msg % synclient_list_cmd)
        # Ungrab the device only if it has been grabbed.
        elif self.grab_value == 1:
            ungrab_cmd = self.grab_device % 0
            try:
                utils.system(ungrab_cmd)
            except:
                raise error.TestError('Fail to execute: %s' % ungrab_cmd)
            logging.info('The synaptics device file is ungrabbed now.')

    def playback(self, packet_data_file):
        option_slot0 = '--insert-slot0'
        option_output = '--output'
        play_cmd = '%s %s %s %s %s < %s' % (self.playback_program,
                                            self.trackpad_device_file,
                                            option_slot0,
                                            option_output,
                                            TrackpadDevice.DEVICE_TIME_FILE,
                                            packet_data_file)
        utils.system(play_cmd)

    def __del__(self):
        # Grab the device again only if it was originally grabbed.
        if self.trackpad_driver == 'synaptics' and self.grab_value == 1:
            grab_cmd = self.grab_device % 1
            try:
                utils.system(grab_cmd)
            except:
                raise error.TestError('Fail to execute: %s' % grab_cmd)
            logging.info('The synaptics device file is grabbed successfully.')

        # Remove the temporary device time file
        if os.path.exists(TrackpadDevice.DEVICE_TIME_FILE):
            try:
                os.remove(TrackpadDevice.DEVICE_TIME_FILE)
            except:
                logging.warn('Cannot remove the device time file: %s.' %
                             TrackpadDevice.DEVICE_TIME_FILE)
