# 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 mtb module

import glob
import os
import sys
import unittest

import common_unittest_utils
import fuzzy
import mtb
import test_conf as conf

from firmware_constants import AXIS, GV, MTB, VAL


def get_mtb_packets(gesture_filename):
    """Get mtb_packets object by reading the gesture file."""
    parser = mtb.MtbParser()
    packets = parser.parse_file(gesture_filename)
    mtb_packets = mtb.Mtb(packets)
    return mtb_packets


class FakeMtb(mtb.Mtb):
    """A fake MTB class to set up x and y positions directly."""
    def __init__(self, list_x, list_y):
        self.list_x = list_x
        self.list_y = list_y

    def get_x_y(self, target_slot):
        """Return list_x, list_y directly."""
        return (self.list_x, self.list_y)


class MtbTest(unittest.TestCase):
    """Unit tests for mtb.Mtb class."""

    def setUp(self):
        self.test_dir = os.path.join(os.getcwd(), 'tests')
        self.data_dir = os.path.join(self.test_dir, 'data')

    def _get_filepath(self, filename, gesture_dir=''):
        return os.path.join(self.data_dir, gesture_dir, filename)

    def _get_range_middle(self, criteria):
        """Get the middle range of the criteria."""
        fc = fuzzy.FuzzyCriteria(criteria)
        range_min , range_max = fc.get_criteria_value_range()
        range_middle = (range_min + range_max) / 2.0
        return range_middle

    def _call_get_reversed_motions(self, list_x, list_y, expected_x,
                                   expected_y, direction):
        mtb = FakeMtb(list_x, list_y)
        displacement = mtb.get_reversed_motions(0, direction, ratio=0.1)
        self.assertEqual(displacement[AXIS.X], expected_x)
        self.assertEqual(displacement[AXIS.Y], expected_y)

    def test_get_reversed_motions_no_reversed(self):
        list_x = (10, 22 ,36, 54, 100)
        list_y = (1, 2 ,6, 10, 22)
        self._call_get_reversed_motions(list_x, list_y, 0, 0, GV.TLBR)

    def test_get_reversed_motions_reversed_x_y(self):
        list_x = (10, 22 ,36, 154, 100)
        list_y = (1, 2 ,6, 30, 22)
        self._call_get_reversed_motions(list_x, list_y, -54, -8, GV.TLBR)

    def _test_get_x_y(self, filename, slot, expected_value):
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        list_x, list_y = mtb_packets.get_x_y(slot)
        points = zip(list_x, list_y)
        self.assertEqual(len(points), expected_value)

    def test_get_x_y(self):
        self._test_get_x_y('one_finger_with_slot_0.dat', 0, 12)
        self._test_get_x_y('one_finger_without_slot_0.dat', 0, 9)
        self._test_get_x_y('two_finger_with_slot_0.dat', 0, 121)
        self._test_get_x_y('two_finger_with_slot_0.dat', 1, 59)
        self._test_get_x_y('two_finger_without_slot_0.dat', 0, 104)
        self._test_get_x_y('two_finger_without_slot_0.dat', 1, 10)

    def test_get_x_y_multiple_slots(self):
        filename = 'x_y_multiple_slots.dat'
        filepath = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(filepath)
        slots = (0, 1)
        list_x, list_y = mtb_packets.get_x_y_multiple_slots(slots)
        expected_list_x = {}
        expected_list_y = {}
        expected_list_x[0] = [1066, 1068, 1082, 1183, 1214, 1285, 1322, 1351,
                              1377, 1391]
        expected_list_y[0] = [561, 559, 542, 426, 405, 358, 328, 313, 304, 297]
        expected_list_x[1] = [770, 769, 768, 758, 697, 620, 585, 565, 538, 538]
        expected_list_y[1] = [894, 894, 895, 898, 927, 968, 996, 1003, 1013,
                              1013]
        for slot in slots:
            self.assertEqual(list_x[slot], expected_list_x[slot])
            self.assertEqual(list_y[slot], expected_list_y[slot])

    def test_get_x_y_multiple_slots2(self):
        """Test slot state machine.

        When the last slot in the previous packet is slot 0, and the first
        slot in the current packet is also slot 0, the slot 0 will not be
        displayed explicitly. This test ensures that the slot stat machine
        is tracked properly.
        """
        filename = 'pinch_to_zoom.zoom_in.dat'
        filepath = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(filepath)
        slots = (0, 1)
        list_x, list_y = mtb_packets.get_x_y_multiple_slots(slots)
        expected_final_x = {}
        expected_final_y = {}
        expected_final_x[0] = 1318
        expected_final_y[0] = 255
        expected_final_x[1] = 522
        expected_final_y[1] = 1232
        for slot in slots:
            self.assertEqual(list_x[slot][-1], expected_final_x[slot])
            self.assertEqual(list_y[slot][-1], expected_final_y[slot])

    def _test_get_points_for_every_tracking_id(self, filename, expected_values):
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        points = mtb_packets.get_points_for_every_tracking_id()
        for tracking_id in expected_values:
            self.assertEqual(len(points[tracking_id][MTB.POINTS]),
                             expected_values[tracking_id])

    def test_get_points_for_every_tracking_id(self):
        self._test_get_points_for_every_tracking_id(
                'two_finger_with_slot_0.dat', {2101: 121, 2102: 59})
        self._test_get_points_for_every_tracking_id(
                'two_finger_without_slot_0.dat', {2097: 104, 2098: 10})

    def _test_drumroll(self, filename, check_func):
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        max_distance = mtb_packets.get_max_distance_of_all_tracking_ids()
        self.assertTrue(check_func(max_distance))

    def test_drumroll(self):
        check_func = lambda x: x >= 50
        self._test_drumroll('drumroll_lumpy.dat', check_func)

    def test_drumroll1(self):
        check_func = lambda x: x >= 50
        self._test_drumroll('drumroll_lumpy_1.dat', check_func)

    def test_drumroll_link(self):
        check_func = lambda x: x >= 50
        self._test_drumroll('drumroll_link.dat', check_func)

    def test_no_drumroll_link(self):
        check_func = lambda x: x <= 20
        self._test_drumroll('no_drumroll_link.dat', check_func)

    def test_no_drumroll_link(self):
        check_func = lambda x: x >= 50
        self._test_drumroll('drumroll_link_2.dat', check_func)

    def test_get_points_for_every_tracking_id2(self):
        gesture_filename = self._get_filepath('drumroll_link_2.dat')
        mtb_packets = get_mtb_packets(gesture_filename)
        points = mtb_packets.get_points_for_every_tracking_id()
        # Check points in two tracking IDs: 95 and 104
        # Tracking ID 95: slot 0 (no explicit slot 0 assigned). This is the
        #                 only slot in the packet.
        list_95 = [(789, 358), (789, 358), (789, 358), (789, 358), (789, 358),
                   (789, 359), (789, 359), (789, 359), (788, 359), (788, 360),
                   (788, 360), (787, 360), (787, 361), (490, 903), (486, 892),
                   (484, 895), (493, 890), (488, 893), (488, 893), (489, 893),
                   (490, 893), (490, 893), (491, 893), (492, 893)]
        # Tracking ID 104: slot 0 (explicit slot 0 assigned). This is the 2nd
        #                  slot in the packet. A slot 1 has already existed.
        list_104 = [(780, 373), (780, 372), (780, 372), (780, 372), (780, 373),
                    (780, 373), (781, 373)]
        self.assertEqual(list_95, points[95][MTB.POINTS])
        self.assertEqual(list_104, points[104][MTB.POINTS])

    def test_get_points_for_every_tracking_id3(self):
        filename = 'drumroll_3.dat'
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        points = mtb_packets.get_points_for_every_tracking_id()
        # Check points in one tracking ID: 582
        # Tracking ID 582: slot 9. This is the 2nd slot in the packet.
        #                  A slot 8 has already existed.
        list_582 = [(682, 173), (667, 186), (664, 189), (664, 190), (664, 189),
                    (665, 189), (665, 189), (667, 188), (675, 185), (683, 181),
                    (693, 172), (469, 381), (471, 395), (471, 396)]
        self.assertEqual(list_582, points[582][MTB.POINTS])

    def test_convert_to_evemu_format(self):
        evemu_filename = self._get_filepath('one_finger_swipe.evemu.dat')
        mtplot_filename = self._get_filepath('one_finger_swipe.dat')
        packets = mtb.MtbParser().parse_file(mtplot_filename)
        evemu_converted_iter = iter(mtb.convert_to_evemu_format(packets))
        with open(evemu_filename) as evemuf:
            for line_evemu_original in evemuf:
                evemu_original = line_evemu_original.split()
                evemu_converted_str = next(evemu_converted_iter, None)
                self.assertNotEqual(evemu_converted_str, None)
                if evemu_converted_str:
                    evemu_converted = evemu_converted_str.split()
                self.assertEqual(len(evemu_original), 5)
                self.assertEqual(len(evemu_converted), 5)
                # Skip the timestamps for they are different in both formats.
                # Prefix, type, code, and value should be the same.
                for i in [0, 2, 3, 4]:
                    self.assertEqual(evemu_original[i], evemu_converted[i])

    def test_calc_farthest_distance(self):
        filename = 'drumroll_no_points.dat'
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        points = mtb_packets.get_points_for_every_tracking_id()
        for tracking_id in points.keys():
            # The function _calc_farthest_distance() should not incur any
            # exception in the tracking id 242 in which there are no points.
            if tracking_id == 242:
                this_id_points = points[tracking_id][MTB.POINTS]
                distance = mtb_packets._calc_farthest_distance(this_id_points)
                self.assertEqual(distance, 0)

    def test_get_largest_gap_ratio(self):
        """Test get_largest_gap_ratio for one-finger and two-finger gestures."""
        # The following files come with noticeable large gaps.
        list_large_ratio = [
            'one_finger_tracking.left_to_right.slow_1.dat',
            'two_finger_gaps.vertical.dat',
            'two_finger_gaps.horizontal.dat',
            'resting_finger_2nd_finger_moving_segment_gaps.dat',
            'gap_new_finger_arriving_or_departing.dat',
            'one_stationary_finger_2nd_finger_moving_gaps.dat',
            'resting_finger_2nd_finger_moving_gaps.dat',
        ]
        gesture_slots = {
            'one_finger': [0,],
            'two_finger': [0, 1],
            'resting_finger': [1,],
            'gap_new_finger': [0,],
            'one_stationary_finger': [1,],
        }

        range_middle = self._get_range_middle(conf.no_gap_criteria)
        gap_data_dir = self._get_filepath('gaps')
        gap_data_filenames = glob.glob(os.path.join(gap_data_dir, '*.dat'))
        for filename in gap_data_filenames:
            mtb_packets = get_mtb_packets(filename)
            base_filename = os.path.basename(filename)

            # What slots to check are based on the gesture name.
            slots = []
            for gesture in gesture_slots:
                if base_filename.startswith(gesture):
                    slots = gesture_slots[gesture]
                    break

            for slot in slots:
                largest_gap_ratio = mtb_packets.get_largest_gap_ratio(slot)
                if base_filename in list_large_ratio:
                    self.assertTrue(largest_gap_ratio >= range_middle)
                else:
                    self.assertTrue(largest_gap_ratio < range_middle)

    def test_get_largest_accumulated_level_jumps(self):
        """Test get_largest_accumulated_level_jumps."""
        dir_level_jumps = 'drag_edge_thumb'

        filenames = [
            # filenames with level jumps
            # ----------------------------------
            'drag_edge_thumb.horizontal.dat',
            'drag_edge_thumb.horizontal_2.dat',
            # test no points in some tracking ID
            'drag_edge_thumb.horizontal_3.no_points.dat',
            'drag_edge_thumb.vertical.dat',
            'drag_edge_thumb.vertical_2.dat',
            'drag_edge_thumb.diagonal.dat',
            # Change tracking IDs quickly.
            'drag_edge_thumb.horizontal_4.change_ids_quickly.dat',

            # filenames without level jumps
            # ----------------------------------
            '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',
            # Rather small level jumps
            'drag_edge_thumb.horizontal_5.small_level_jumps.curvy.dat',
        ]

        largest_level_jumps = {
            # Large jumps
            'drag_edge_thumb.horizontal.dat': {AXIS.X: 0, AXIS.Y: 97},
            # Smaller jumps
            'drag_edge_thumb.horizontal_2.dat': {AXIS.X: 0, AXIS.Y: 24},
            # test no points in some tracking ID
            'drag_edge_thumb.horizontal_3.no_points.dat':
                    {AXIS.X: 97, AXIS.Y: 88},
            # Change tracking IDs quickly.
            'drag_edge_thumb.horizontal_4.change_ids_quickly.dat':
                    {AXIS.X: 0, AXIS.Y: 14},
            # Large jumps
            'drag_edge_thumb.vertical.dat': {AXIS.X: 54, AXIS.Y: 0},
            # The first slot 0 comes with smaller jumps only.
            'drag_edge_thumb.vertical_2.dat': {AXIS.X: 20, AXIS.Y: 0},
            # Large jumps
            'drag_edge_thumb.diagonal.dat': {AXIS.X: 84, AXIS.Y: 58},
        }

        target_slot = 0
        for filename in filenames:
            filepath = self._get_filepath(filename, gesture_dir=dir_level_jumps)
            packets = get_mtb_packets(filepath)
            displacements = packets.get_displacements_for_slots(target_slot)

            # There are no level jumps in a curvy line.
            file_with_level_jump = 'curvy' not in filename

            # Check the first slot only
            tids = displacements.keys()
            tids.sort()
            tid = tids[0]
            # Check both axis X and axis Y
            for axis in AXIS.LIST:
                disp = displacements[tid][axis]
                jump = packets.get_largest_accumulated_level_jumps(disp)
                # Verify that there are no jumps in curvy files, and
                #        that there are jumps in the other files.
                expected_jump = (0 if not file_with_level_jump
                                   else largest_level_jumps[filename][axis])
                self.assertTrue(jump == expected_jump)

    def _test_get_report_rate(self, filename, value):
        """Test get_report_rate."""
        gesture_filename = self._get_filepath(filename)
        mtb_packets = get_mtb_packets(gesture_filename)
        report_rate = round(mtb_packets.get_report_rate(), 2)
        self.assertAlmostEqual(report_rate, value)

    def test_get_report_rate(self):
        """Test get_report_rate."""
        filename = '2f_scroll_diagonal.dat'
        self._test_get_report_rate('2f_scroll_diagonal.dat', 40.31)

        filename = 'one_finger_with_slot_0.dat'
        self._test_get_report_rate(filename, 148.65)

        filename = 'two_close_fingers_merging_changed_ids_gaps.dat'
        self._test_get_report_rate(filename, 53.12)


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