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

from collections import defaultdict
import logging
import os
import subprocess
import tempfile
import time

from autotest_lib.client.bin import test
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error


class touch_playback_test_base(test.test):
    """Base class for touch tests involving playback."""
    version = 1

    _PLAYBACK_COMMAND = 'evemu-play --insert-slot0 %s < %s'
    _INPUTCONTROL = '/opt/google/input/inputcontrol'
    _DEFAULT_SCROLL = 5000

    @property
    def _has_touchpad(self):
        """True if device under test has a touchpad; else False."""
        return self._has_inputs['touchpad']

    @property
    def _has_touchscreen(self):
        """True if device under test has a touchscreen; else False."""
        return self._has_inputs['touchscreen']

    @property
    def _has_mouse(self):
        """True if device under test has or emulates a USB mouse; else False."""
        return self._has_inputs['mouse']

    def _find_device_properties(self, device):
        """Given device (e.g. /dev/input/event7), return a string of properties.

        @return: string of properties.

        """
        temp_file = tempfile.NamedTemporaryFile()
        filename = temp_file.name
        evtest_process = subprocess.Popen(['evtest', device], stdout=temp_file)

        def find_exit():
            """Polling function for end of output."""
            interrupt_cmd = 'grep "interrupt to exit" %s | wc -l' % filename
            line_count = utils.run(interrupt_cmd).stdout.strip()
            return line_count != '0'

        utils.poll_for_condition(find_exit)
        evtest_process.kill()
        temp_file.seek(0)
        props = temp_file.read()
        temp_file.close() #deletes the temporary file
        return props

    def _determine_input_type(self, event):
        """Find event's list of propertiles and return input type (if any)."""
        props = self._find_device_properties(event)
        if props.find('REL_X') >= 0 and props.find('REL_Y') >= 0:
            if (props.find('ABS_MT_POSITION_X') >= 0 and
                props.find('ABS_MT_POSITION_Y') >= 0):
                return 'multitouch_mouse'
            else:
                return 'mouse'
        if props.find('ABS_X') >= 0 and props.find('ABS_Y') >= 0:
            if (props.find('BTN_STYLUS') >= 0 or
                props.find('BTN_STYLUS2') >= 0 or
                props.find('BTN_TOOL_PEN') >= 0):
                return 'tablet'
            if (props.find('ABS_PRESSURE') >= 0 or
                props.find('BTN_TOUCH') >= 0):
                if (props.find('BTN_LEFT') >= 0 or
                    props.find('BTN_MIDDLE') >= 0 or
                    props.find('BTN_RIGHT') >= 0 or
                    props.find('BTN_TOOL_FINGER') >= 0):
                    return 'touchpad'
                else:
                    return 'touchscreen'
            if props.find('BTN_LEFT') >= 0:
                return 'touchscreen'
        return

    def warmup(self, mouse_props=None, mouse_name=''):
        """Determine the nodes of all present touch devices, if any.

        Cycle through all possible /dev/input/event* and find which ones
        are touchpads, touchscreens, mice, etc.
        These events can be used for playback later.
        Emulate a USB mouse if a property file is provided.
        Check if the inputcontrol script is avaiable on the disk.

        @param mouse_props: property file for a mouse to emulate.  Created
                            using 'evemu-describe /dev/input/X'.
        @param mouse_name: name of expected mouse.

        """
        self._has_inputs = defaultdict(bool)
        self._nodes = defaultdict(str)
        self._names = defaultdict(str)
        self._device_emulation_process = None
        self._autotest_ext = None
        self._has_inputcontrol = os.path.isfile(self._INPUTCONTROL)

        def _get_input_events():
            return utils.run('ls /dev/input/event*').stdout.strip().split()

        # Emulate mouse if property file was provided.
        if mouse_props:
            logging.info('Emulating mouse: %s', mouse_props)
            events_before = len(_get_input_events())
            self._device_emulation_process = subprocess.Popen(
                    ['evemu-device', mouse_props], stdout=subprocess.PIPE)
            self._names['mouse'] = mouse_name
            utils.poll_for_condition(
                    lambda: len(_get_input_events()) > events_before,
                    exception=error.TestError('Error emulating mouse!'))

        # Cycle through all possible input devices.
        input_events = _get_input_events()
        for event in input_events:
            input_type = self._determine_input_type(event)
            if input_type:
                logging.info('Found %s at %s.', input_type, event)

                class_folder = event.replace('dev', 'sys/class')
                name_file = os.path.join(class_folder, 'device', 'name')
                name = 'unknown'
                if os.path.isfile(name_file):
                    name = utils.run('cat %s' % name_file).stdout.strip()
                # If a particular device is expected, make sure this matches.
                if self._names[input_type]:
                    if self._names[input_type] != name:
                        continue

                # Save this device information for later use.
                self._has_inputs[input_type] = True
                self._nodes[input_type] = event
                self._names[input_type] = name
                logging.info('%s is %s.', input_type, name)


    def _playback(self, filepath, touch_type='touchpad'):
        """Playback a given set of touch movements.

        @param filepath: path to the movements file on the DUT.
        @param touch_type: name of device type; 'touchpad' by default.
                           Types are returned by the _determine_input_type()
                           function.
                           self._has_inputs[touch_type] must be True.

        """
        assert(self._has_inputs[touch_type])
        node = self._nodes[touch_type]
        logging.info('Playing back finger-movement on %s, file=%s.', node,
                     filepath)
        utils.run(self._PLAYBACK_COMMAND % (node, filepath))

    def _blocking_playback(self, filepath, touch_type='touchpad'):
        """Playback a given set of touch movements and wait.

        @param filepath: path to the movements file on the DUT.
        @param touch_type: name of device type; 'touchpad' by default.
                           Types are returned by the _determine_input_type()
                           function.
                           self._has_inputs[touch_type] must be True.

        """
        with open(filepath) as fh:
            lines = fh.readlines()
            start = float(lines[0].split(' ')[1])
            end = float(lines[-1].split(' ')[1])
            sleep_time = end - start
        self._playback(filepath, touch_type)
        logging.info('Sleeping for %s seconds during playback.', sleep_time)
        time.sleep(sleep_time)

    def _set_touch_setting_by_inputcontrol(self, setting, value):
        """Set a given touch setting the given value by inputcontrol.

        @param setting: Name of touch setting, e.g. 'tapclick'.
        @param value: True for enabled, False for disabled.

        """
        cmd_value = 1 if value else 0
        utils.run('%s --%s %d' % (self._INPUTCONTROL, setting, cmd_value))
        logging.info('%s turned %s.', setting, 'on' if value else 'off')

    def _set_touch_setting(self, inputcontrol_setting, autotest_ext_setting,
                           value):
        """Set a given touch setting the given value.

        @param inputcontrol_setting: Name of touch setting for the inputcontrol
                                     script, e.g. 'tapclick'.
        @param autotest_ext_setting: Name of touch setting for the autotest
                                     extension, e.g. 'TapToClick'.
        @param value: True for enabled, False for disabled.

        """
        if self._has_inputcontrol:
          self._set_touch_setting_by_inputcontrol(inputcontrol_setting, value)
        elif self._autotest_ext is not None:
          self._autotest_ext.EvaluateJavaScript(
                  'chrome.autotestPrivate.set%s(%s);'
                  % (autotest_ext_setting, ("%s" % value).lower()))
        else:
          raise error.TestFail('Both the inputcontrol and the autotest '
                               'extension are not availble')

    def _set_australian_scrolling(self, value):
        """Set australian scrolling to the given value.

        @param value: True for enabled, False for disabled.

        """
        self._set_touch_setting('australian_scrolling', 'NaturalScroll', value)

    def _set_tap_to_click(self, value):
        """Set tap-to-click to the given value.

        @param value: True for enabled, False for disabled.

        """
        self._set_touch_setting('tapclick', 'TapToClick', value)

    def _set_tap_dragging(self, value):
        """Set tap dragging to the given value.

        @param value: True for enabled, False for disabled.

        """
        self._set_touch_setting('tapdrag', 'TapDragging', value)

    def cleanup(self):
        if self._device_emulation_process:
            self._device_emulation_process.kill()

    def _reload_page(self):
        """Reloads test page.  Presuposes self._tab.

        @raise: TestError if page is not reset.

        """
        self._tab.Navigate(self._tab.url)
        self._tab.WaitForDocumentReadyStateToBeComplete()

    def _set_autotest_ext(self, ext):
        """Set the autotest extension.

        @ext: the autotest extension object.

        """
        self._autotest_ext = ext

    def _set_default_scroll_position(self):
        """Set scroll position of page to default.  Presuposes self._tab."""
        self._tab.EvaluateJavaScript(
                'document.body.scrollTop=%s' % self._DEFAULT_SCROLL)

    def _get_scroll_position(self):
        """Return current scroll position of page.  Presuposes self._tab."""
        return int(self._tab.EvaluateJavaScript('document.body.scrollTop'))

    def _wait_for_default_scroll_position(self):
        """Wait for page to be at the default scroll position.

        @raise: TestError if page either does not move or does not stop moving.

        """
        utils.poll_for_condition(
                lambda: self._get_scroll_position() == self._DEFAULT_SCROLL,
                exception=error.TestError('Page not set to default scroll!'))

    def _wait_for_scroll_position_to_settle(self):
        """Wait for page to move and then stop moving.

        @raise: TestError if page either does not move or does not stop moving.

        """
        # Wait until page starts moving.
        utils.poll_for_condition(
                lambda: self._get_scroll_position() != self._DEFAULT_SCROLL,
                exception=error.TestError('No scrolling occurred!'), timeout=30)

        # Wait until page has stopped moving.
        self._previous = self._DEFAULT_SCROLL
        def _movement_stopped():
            current = self._get_scroll_position()
            result = current == self._previous
            self._previous = current
            return result

        utils.poll_for_condition(
                lambda: _movement_stopped(), sleep_interval=1,
                exception=error.TestError('Page did not stop moving!'),
                timeout=30)

