# Copyright (c) 2012 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 contains unit tests for the classes in the validators module."""

import os.path
import unittest

import common_unittest_utils
import common_util
import test_conf as conf

from common_unittest_utils import MockTouchpadDevice, parse_tests_data
from firmware_constants import GV
from validators import (CountPacketsValidator,
                        CountTrackingIDValidator,
                        DrumrollValidator,
                        LinearityValidator,
                        NoGapValidator,
                        NoLevelJumpValidator,
                        NoReversedMotionValidator,
                        PhysicalClickValidator,
                        PinchValidator,
                        RangeValidator,
                        ReportRateValidator,
                        StationaryFingerValidator,
)


class BaseValidatorTest(unittest.TestCase):
    """A base class for all ValidatorTest classes."""

    def setUp(self):
        """Set up mocked devices for various test boards."""
        # define supported platforms
        self.ALEX= 'alex'
        self.LUMPY = 'lumpy'
        self.LINK = 'link'
        self.supported_platforms = [self.ALEX, self.LUMPY, self.LINK]
        self.mock_device = {}
        description_path = common_unittest_utils.get_device_description_path()

        for platform in self.supported_platforms:
            description_filename = '%s.device' % platform
            description_filepath = os.path.join(description_path,
                                                description_filename)
            if not os.path.isfile(description_filepath):
                self.mock_device[platform] = None
                warn_msg = 'Warning: device description file %s does not exist'
                print msg % description_filepath
                continue
            query_cmd = 'cat %s' % description_filepath
            device_description = common_util.simple_system_output(query_cmd)
            self.mock_device[platform] = MockTouchpadDevice(device_description)


class CountTrackingIDValidatorTest(BaseValidatorTest):
    """Unit tests for CountTrackingIDValidator class."""

    def setUp(self):
        super(CountTrackingIDValidatorTest, self).setUp()

    def _test_count_tracking_id(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = CountTrackingIDValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.get_score()

    def test_two_finger_id_change(self):
        """Two two fingers id change.

        Issue 7867: Cyapa : Two finger scroll, tracking ids change
        """
        filename = 'two_finger_id_change.dat'
        score = self._test_count_tracking_id(filename, '== 2',
                                             self.mock_device[self.LUMPY])
        self.assertTrue(score == 0)

    def test_one_finger_fast_swipe_id_split(self):
        """One finger fast swipe resulting in IDs split.

        Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe
        """
        filename = 'one_finger_fast_swipe_id_split.dat'
        score = self._test_count_tracking_id(filename, '== 1',
                                             self.mock_device[self.LUMPY])
        self.assertTrue(score == 0)

    def test_two_fingers_fast_flick_id_split(self):
        """Two figners fast flick resulting in IDs split.

        Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe
        """
        filename = 'two_finger_fast_flick_id_split.dat'
        score = self._test_count_tracking_id(filename, '== 2',
                                             self.mock_device[self.LUMPY])
        self.assertTrue(score == 0)


class DrumrollValidatorTest(BaseValidatorTest):
    """Unit tests for DrumrollValidator class."""

    def setUp(self):
        super(DrumrollValidatorTest, self).setUp()
        self.criteria = conf.drumroll_criteria

    def _test_drumroll(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = DrumrollValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.get_score()

    def test_drumroll_lumpy(self):
        """Should catch the drumroll on lumpy.

        Issue 7809: Lumpy: Drumroll bug in firmware
        """
        filename = 'drumroll_lumpy.dat'
        score = self._test_drumroll(filename, self.criteria,
                                    self.mock_device[self.LUMPY])
        self.assertTrue(score == 0)

    def test_drumroll_lumpy_1(self):
        """Should catch the drumroll on lumpy.

        Issue 7809: Lumpy: Drumroll bug in firmware
        """
        filename = 'drumroll_lumpy_1.dat'
        score = self._test_drumroll(filename, self.criteria,
                                    self.mock_device[self.LUMPY])
        self.assertTrue(score == 0)

    def test_no_drumroll_link(self):
        """Should pass (score == 1) when there is no drumroll.

        Issue 7809: Lumpy: Drumroll bug in firmware
        """
        filename = 'no_drumroll_link.dat'
        score = self._test_drumroll(filename, self.criteria,
                                    self.mock_device[self.LINK])
        self.assertTrue(score == 1)


class LinearityValidatorTest(BaseValidatorTest):
    """Unit tests for LinearityValidator class."""

    def setUp(self):
        super(LinearityValidatorTest, self).setUp()
        self.criteria = conf.linearity_criteria

    def _test_linearity_criteria(self, criteria_str, slots, device):
        filename = '2f_scroll_diagonal.dat'
        direction = GV.DIAGONAL
        packets = parse_tests_data(filename)
        scores = {}
        for slot in slots:
            validator = LinearityValidator(criteria_str, device=device,
                                           slot=slot)
            scores[slot] = validator.check(packets, direction).get_score()
        return scores

    def test_linearity_criteria0(self):
        """The scores are 0s due to strict criteria."""
        criteria_str = '<= 0.01, ~ +0.01'
        scores = self._test_linearity_criteria(criteria_str, (0, 1),
                                               self.mock_device[self.ALEX])
        self.assertTrue(scores[0] == 0)
        self.assertTrue(scores[1] == 0)

    def test_linearity_criteria1(self):
        """The validator gets score betwee 0 and 1."""
        criteria_str = '<= 0.01, ~ +3.0'
        scores = self._test_linearity_criteria(criteria_str, (0, 1),
                                               self.mock_device[self.ALEX])
        self.assertTrue(scores[0] > 0 and scores[0] < 1)
        self.assertTrue(scores[1] > 0 and scores[1] < 1)

    def test_linearity_criteria2(self):
        """The validator gets score of 1 due to very relaxed criteria."""
        criteria_str = '<= 10, ~ +10'
        scores = self._test_linearity_criteria(criteria_str, (0, 1),
                                               self.mock_device[self.ALEX])
        self.assertTrue(scores[0] == 1)
        self.assertTrue(scores[1] == 1)

    def _test_linearity_validator(self, filename, criteria, slots, device,
                                  direction):
        packets = parse_tests_data(filename)
        scores = {}
        if isinstance(slots, int):
            slots = (slots,)
        for slot in slots:
            validator = LinearityValidator(criteria, device=device, slot=slot)
            scores[slot] = validator.check(packets, direction).get_score()
        return scores

    def test_two_finger_jagged_lines(self):
        """Test two-finger jagged lines."""
        filename = 'two_finger_tracking.diagonal.slow.dat'
        scores = self._test_linearity_validator(filename, self.criteria, (0, 1),
                self.mock_device[self.LUMPY], GV.DIAGONAL)
        self.assertTrue(scores[0] < 0.7)
        self.assertTrue(scores[1] < 0.7)

    def test_stationary_finger_fat_finger_wobble(self):
        """Test fat finger horizontal move with a stationary resting finger
        results in a wobble.

        Issue 7551: Fat finger horizontal move with a stationary resting
        finger results in a wobble.
        """
        filename = 'stationary_finger_fat_finger_wobble.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 1,
                self.mock_device[self.LUMPY], GV.HORIZONTAL)
        self.assertTrue(scores[1] <= 0.1)

    def test_thumb_edge(self):
        """Test thumb edge wobble.

        Issue 7554: thumb edge behavior.
        """
        filename = 'thumb_edge_wobble.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                self.mock_device[self.LUMPY], GV.HORIZONTAL)
        self.assertTrue(scores[0] < 0.5)

    def test_two_close_fingers_merging_changed_ids_gaps(self):
        """Test close finger merging - causes id changes

        Issue 7555: close finger merging - causes id changes.
        """
        filename = 'two_close_fingers_merging_changed_ids_gaps.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                self.mock_device[self.LUMPY], GV.VERTICAL)
        self.assertTrue(scores[0] < 0.3)

    def test_jagged_two_finger_scroll(self):
        """Test jagged two finger scroll.

        Issue 7650: Cyapa : poor two fat fingers horizontal scroll performance -
        jagged lines
        """
        filename = 'jagged_two_finger_scroll_horizontal.dat'
        scores = self._test_linearity_validator(filename, self.criteria, (0, 1),
                self.mock_device[self.LUMPY], GV.HORIZONTAL)
        self.assertTrue(scores[0] < 0.3)
        self.assertTrue(scores[1] < 0.3)

    def test_first_point_jump(self):
        """Test the first point jump

        At slot 0, the positions of (x, y) looks like
            x: 208, 241, 242, 245, 246, ...
            y: 551, 594, 595, 597, 598, ...
        Note that the the first y position is a jump.
        """
        filename = 'two_finger_tracking.bottom_left_to_top_right.slow.dat'
        scores = self._test_linearity_validator(filename, self.criteria, 0,
                self.mock_device[self.LUMPY], GV.DIAGONAL)
        self.assertTrue(scores[0] < 0.3)

    def test_simple_linear_regression0(self):
        device = self.mock_device[self.LUMPY]
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=device, slot=0)
        validator.init_check()
        # A perfect line from bottom left to top right
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 80, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertEqual(spmse, 0)

    def test_simple_linear_regression1(self):
        device = self.mock_device[self.LUMPY]
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=device, slot=0)
        validator.init_check()
        # Another perfect line from top left to bottom right
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [160, 140, 120, 100, 80, 60, 40, 20]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertEqual(spmse, 0)

    def test_simple_linear_regression2(self):
        device = self.mock_device[self.LUMPY]
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=device, slot=0)
        validator.init_check()
        # An outlier in y axis
        list_x = [1, 2, 3, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 70, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertTrue(spmse > 0)

    def test_simple_linear_regression3(self):
        device = self.mock_device[self.LUMPY]
        validator = LinearityValidator('<= 0.2, ~ +0.3', device=device, slot=0)
        validator.init_check()
        # Repeated values in x axis
        list_x = [1, 2, 2, 4, 5, 6, 7, 8]
        list_y = [20, 40, 60, 80, 100, 120, 140, 160]
        spmse = validator._simple_linear_regression(list_x, list_y)
        self.assertTrue(spmse > 0)


class NoGapValidatorTest(BaseValidatorTest):
    """Unit tests for NoGapValidator class."""
    GAPS_SUBDIR = 'gaps'

    def setUp(self):
        super(NoGapValidatorTest, self).setUp()
        self.criteria = conf.no_gap_criteria

    def _test_no_gap(self, filename, criteria, device, slot):
        file_subpath = os.path.join(self.GAPS_SUBDIR, filename)
        packets = parse_tests_data(file_subpath)
        validator = NoGapValidator(criteria, device=device, slot=slot)
        vlog = validator.check(packets)
        return vlog.get_score()

    def test_two_finger_scroll_gaps(self):
        """Test that there are gaps in the two finger scroll gesture.

        Issue 7552: Cyapa : two finger scroll motion produces gaps in tracking
        """
        filename = 'two_finger_gaps.horizontal.dat'
        mock_device = self.mock_device[self.LUMPY]
        score0 = self._test_no_gap(filename, self.criteria, mock_device, 0)
        score1 = self._test_no_gap(filename, self.criteria, mock_device, 1)
        self.assertTrue(score0 <= 0.1)
        self.assertTrue(score1 <= 0.1)

    def test_gap_new_finger_arriving_or_departing(self):
        """Test gap when new finger arriving or departing.

        Issue: 8005: Cyapa : gaps appear when new finger arrives or departs
        """
        filename = 'gap_new_finger_arriving_or_departing.dat'
        mock_device = self.mock_device[self.LUMPY]
        score = self._test_no_gap(filename, self.criteria, mock_device, 0)
        self.assertTrue(score <= 0.3)

    def test_one_stationary_finger_2nd_finger_moving_gaps(self):
        """Test one stationary finger resulting in 2nd finger moving gaps."""
        filename = 'one_stationary_finger_2nd_finger_moving_gaps.dat'
        mock_device = self.mock_device[self.LUMPY]
        score = self._test_no_gap(filename, self.criteria, mock_device, 1)
        self.assertTrue(score <= 0.1)

    def test_resting_finger_2nd_finger_moving_gaps(self):
        """Test resting finger resulting in 2nd finger moving gaps.

        Issue 7648: Cyapa : Resting finger plus one finger move generates a gap
        """
        filename = 'resting_finger_2nd_finger_moving_gaps.dat'
        mock_device = self.mock_device[self.LUMPY]
        score = self._test_no_gap(filename, self.criteria, mock_device, 1)
        self.assertTrue(score <= 0.3)


class StationaryFingerValidatorTest(BaseValidatorTest):
    """Unit tests for LinearityValidator class."""

    def setUp(self):
        super(StationaryFingerValidatorTest, self).setUp()
        self.criteria = conf.stationary_finger_criteria

    def _test_stationary_finger(self, filename, criteria, device):
        packets = parse_tests_data(filename)
        validator = StationaryFingerValidator(criteria, device=device)
        vlog = validator.check(packets)
        return vlog.get_score()

    def test_stationary_finger_shift(self):
        """Test that the stationary shift due to 2nd finger tapping.

        Issue 7442: Cyapa : Second finger tap events influence stationary finger
        position
        """
        filename = 'stationary_finger_shift_with_2nd_finger_tap.dat'
        device = self.mock_device[self.LUMPY]
        score = self._test_stationary_finger(filename, self.criteria, device)
        self.assertTrue(score <= 0.1)

    def test_stationary_strongly_affected_by_2nd_moving_finger(self):
        """Test stationary finger strongly affected by 2nd moving finger with
        gaps.

        Issue 5812: [Cypress] reported positions of stationary finger strongly
        affected by nearby moving finger
        """
        filename = ('stationary_finger_strongly_affected_by_2nd_moving_finger_'
                    'with_gaps.dat')
        device = self.mock_device[self.LUMPY]
        score = self._test_stationary_finger(filename, self.criteria, device)
        self.assertTrue(score <= 0.1)


class NoLevelJumpValidatorTest(BaseValidatorTest):
    """Unit tests for NoLevelJumpValidator class."""

    def setUp(self):
        super(NoLevelJumpValidatorTest, self).setUp()
        self.criteria = conf.no_level_jump_criteria
        self.gesture_dir = 'drag_edge_thumb'

    def _get_score(self, filename, device):
        validator = NoLevelJumpValidator(self.criteria, device=device,
                                         slots=[0,])
        packets = parse_tests_data(filename, gesture_dir=self.gesture_dir)
        vlog = validator.check(packets)
        score = vlog.get_score()
        return score

    def test_level_jumps(self):
        """Test files with level jumps."""
        filenames = [
            'drag_edge_thumb.horizontal.dat',
            'drag_edge_thumb.horizontal_2.dat',
            'drag_edge_thumb.horizontal_3.no_points.dat',
            'drag_edge_thumb.vertical.dat',
            'drag_edge_thumb.vertical_2.dat',
            'drag_edge_thumb.diagonal.dat',
        ]
        device = self.mock_device[self.LUMPY]
        for filename in filenames:
            self.assertTrue(self._get_score(filename, device) <= 0.6)

    def test_no_level_jumps(self):
        """Test files without level jumps."""
        filenames = [
            'drag_edge_thumb.horizontal.curvy.dat',
            'drag_edge_thumb.horizontal_2.curvy.dat',
            'drag_edge_thumb.vertical.curvy.dat',
            'drag_edge_thumb.vertical_2.curvy.dat',
        ]
        device = self.mock_device[self.LUMPY]
        for filename in filenames:
            self.assertTrue(self._get_score(filename, device) == 1.0)


class ReportRateValidatorTest(BaseValidatorTest):
    """Unit tests for ReportRateValidator class."""
    def setUp(self):
        super(ReportRateValidatorTest, self).setUp()
        self.criteria = conf.report_rate_criteria

    def _get_score(self, filename, device):
        validator = ReportRateValidator(self.criteria, device=device)
        packets = parse_tests_data(filename)
        vlog = validator.check(packets)
        score = vlog.get_score()
        return score

    def test_level_jumps(self):
        """Test files with level jumps."""
        lumpy = self.mock_device[self.LUMPY]

        filename = '2f_scroll_diagonal.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5)

        filename = 'one_finger_with_slot_0.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) >= 0.9)

        filename = 'two_close_fingers_merging_changed_ids_gaps.dat'
        self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5)


if __name__ == '__main__':
  unittest.main()
