#!/bin/env python3
# SPDX-License-Identifier: GPL-2.0
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 Benjamin Tissoires <benjamin.tissoires@gmail.com>
# Copyright (c) 2017 Red Hat, Inc.
#

from . import base
import hidtools.hid
from hidtools.util import BusType
import libevdev
import logging
import pytest

logger = logging.getLogger("hidtools.test.mouse")

# workaround https://gitlab.freedesktop.org/libevdev/python-libevdev/issues/6
try:
    libevdev.EV_REL.REL_WHEEL_HI_RES
except AttributeError:
    libevdev.EV_REL.REL_WHEEL_HI_RES = libevdev.EV_REL.REL_0B
    libevdev.EV_REL.REL_HWHEEL_HI_RES = libevdev.EV_REL.REL_0C


class InvalidHIDCommunication(Exception):
    pass


class MouseData(object):
    pass


class BaseMouse(base.UHIDTestDevice):
    def __init__(self, rdesc, name=None, input_info=None):
        assert rdesc is not None
        super().__init__(name, "Mouse", input_info=input_info, rdesc=rdesc)
        self.left = False
        self.right = False
        self.middle = False

    def create_report(self, x, y, buttons=None, wheels=None, reportID=None):
        """
        Return an input report for this device.

        :param x: relative x
        :param y: relative y
        :param buttons: a (l, r, m) tuple of bools for the button states,
            where ``None`` is "leave unchanged"
        :param wheels: a single value for the vertical wheel or a (vertical, horizontal) tuple for
            the two wheels
        :param reportID: the numeric report ID for this report, if needed
        """
        if buttons is not None:
            left, right, middle = buttons
            if left is not None:
                self.left = left
            if right is not None:
                self.right = right
            if middle is not None:
                self.middle = middle
        left = self.left
        right = self.right
        middle = self.middle
        # Note: the BaseMouse doesn't actually have a wheel but the
        # create_report magic only fills in those fields exist, so let's
        # make this generic here.
        wheel, acpan = 0, 0
        if wheels is not None:
            if isinstance(wheels, tuple):
                wheel = wheels[0]
                acpan = wheels[1]
            else:
                wheel = wheels

        reportID = reportID or self.default_reportID

        mouse = MouseData()
        mouse.b1 = int(left)
        mouse.b2 = int(right)
        mouse.b3 = int(middle)
        mouse.x = x
        mouse.y = y
        mouse.wheel = wheel
        mouse.acpan = acpan
        return super().create_report(mouse, reportID=reportID)

    def event(self, x, y, buttons=None, wheels=None):
        """
        Send an input event on the default report ID.

        :param x: relative x
        :param y: relative y
        :param buttons: a (l, r, m) tuple of bools for the button states,
            where ``None`` is "leave unchanged"
        :param wheels: a single value for the vertical wheel or a (vertical, horizontal) tuple for
            the two wheels
        """
        r = self.create_report(x, y, buttons, wheels)
        self.call_input_event(r)
        return [r]


class ButtonMouse(BaseMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,  # .Usage Page (Generic Desktop)        0
        0x09, 0x02,  # .Usage (Mouse)                       2
        0xa1, 0x01,  # .Collection (Application)            4
        0x09, 0x02,  # ..Usage (Mouse)                      6
        0xa1, 0x02,  # ..Collection (Logical)               8
        0x09, 0x01,  # ...Usage (Pointer)                   10
        0xa1, 0x00,  # ...Collection (Physical)             12
        0x05, 0x09,  # ....Usage Page (Button)              14
        0x19, 0x01,  # ....Usage Minimum (1)                16
        0x29, 0x03,  # ....Usage Maximum (3)                18
        0x15, 0x00,  # ....Logical Minimum (0)              20
        0x25, 0x01,  # ....Logical Maximum (1)              22
        0x75, 0x01,  # ....Report Size (1)                  24
        0x95, 0x03,  # ....Report Count (3)                 26
        0x81, 0x02,  # ....Input (Data,Var,Abs)             28
        0x75, 0x05,  # ....Report Size (5)                  30
        0x95, 0x01,  # ....Report Count (1)                 32
        0x81, 0x03,  # ....Input (Cnst,Var,Abs)             34
        0x05, 0x01,  # ....Usage Page (Generic Desktop)     36
        0x09, 0x30,  # ....Usage (X)                        38
        0x09, 0x31,  # ....Usage (Y)                        40
        0x15, 0x81,  # ....Logical Minimum (-127)           42
        0x25, 0x7f,  # ....Logical Maximum (127)            44
        0x75, 0x08,  # ....Report Size (8)                  46
        0x95, 0x02,  # ....Report Count (2)                 48
        0x81, 0x06,  # ....Input (Data,Var,Rel)             50
        0xc0,        # ...End Collection                    52
        0xc0,        # ..End Collection                     53
        0xc0,        # .End Collection                      54
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, input_info=None):
        super().__init__(rdesc, name, input_info)

    def fake_report(self, x, y, buttons):
        if buttons is not None:
            left, right, middle = buttons
            if left is None:
                left = self.left
            if right is None:
                right = self.right
            if middle is None:
                middle = self.middle
        else:
            left = self.left
            right = self.right
            middle = self.middle

        button_mask = sum(1 << i for i, b in enumerate([left, right, middle]) if b)
        x = max(-127, min(127, x))
        y = max(-127, min(127, y))
        x = hidtools.util.to_twos_comp(x, 8)
        y = hidtools.util.to_twos_comp(y, 8)
        return [button_mask, x, y]


class WheelMouse(ButtonMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,  # Usage Page (Generic Desktop)        0
        0x09, 0x02,  # Usage (Mouse)                       2
        0xa1, 0x01,  # Collection (Application)            4
        0x05, 0x09,  # .Usage Page (Button)                6
        0x19, 0x01,  # .Usage Minimum (1)                  8
        0x29, 0x03,  # .Usage Maximum (3)                  10
        0x15, 0x00,  # .Logical Minimum (0)                12
        0x25, 0x01,  # .Logical Maximum (1)                14
        0x95, 0x03,  # .Report Count (3)                   16
        0x75, 0x01,  # .Report Size (1)                    18
        0x81, 0x02,  # .Input (Data,Var,Abs)               20
        0x95, 0x01,  # .Report Count (1)                   22
        0x75, 0x05,  # .Report Size (5)                    24
        0x81, 0x03,  # .Input (Cnst,Var,Abs)               26
        0x05, 0x01,  # .Usage Page (Generic Desktop)       28
        0x09, 0x01,  # .Usage (Pointer)                    30
        0xa1, 0x00,  # .Collection (Physical)              32
        0x09, 0x30,  # ..Usage (X)                         34
        0x09, 0x31,  # ..Usage (Y)                         36
        0x15, 0x81,  # ..Logical Minimum (-127)            38
        0x25, 0x7f,  # ..Logical Maximum (127)             40
        0x75, 0x08,  # ..Report Size (8)                   42
        0x95, 0x02,  # ..Report Count (2)                  44
        0x81, 0x06,  # ..Input (Data,Var,Rel)              46
        0xc0,        # .End Collection                     48
        0x09, 0x38,  # .Usage (Wheel)                      49
        0x15, 0x81,  # .Logical Minimum (-127)             51
        0x25, 0x7f,  # .Logical Maximum (127)              53
        0x75, 0x08,  # .Report Size (8)                    55
        0x95, 0x01,  # .Report Count (1)                   57
        0x81, 0x06,  # .Input (Data,Var,Rel)               59
        0xc0,        # End Collection                      61
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, input_info=None):
        super().__init__(rdesc, name, input_info)
        self.wheel_multiplier = 1


class TwoWheelMouse(WheelMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,        # Usage Page (Generic Desktop)        0
        0x09, 0x02,        # Usage (Mouse)                       2
        0xa1, 0x01,        # Collection (Application)            4
        0x09, 0x01,        # .Usage (Pointer)                    6
        0xa1, 0x00,        # .Collection (Physical)              8
        0x05, 0x09,        # ..Usage Page (Button)               10
        0x19, 0x01,        # ..Usage Minimum (1)                 12
        0x29, 0x10,        # ..Usage Maximum (16)                14
        0x15, 0x00,        # ..Logical Minimum (0)               16
        0x25, 0x01,        # ..Logical Maximum (1)               18
        0x95, 0x10,        # ..Report Count (16)                 20
        0x75, 0x01,        # ..Report Size (1)                   22
        0x81, 0x02,        # ..Input (Data,Var,Abs)              24
        0x05, 0x01,        # ..Usage Page (Generic Desktop)      26
        0x16, 0x01, 0x80,  # ..Logical Minimum (-32767)          28
        0x26, 0xff, 0x7f,  # ..Logical Maximum (32767)           31
        0x75, 0x10,        # ..Report Size (16)                  34
        0x95, 0x02,        # ..Report Count (2)                  36
        0x09, 0x30,        # ..Usage (X)                         38
        0x09, 0x31,        # ..Usage (Y)                         40
        0x81, 0x06,        # ..Input (Data,Var,Rel)              42
        0x15, 0x81,        # ..Logical Minimum (-127)            44
        0x25, 0x7f,        # ..Logical Maximum (127)             46
        0x75, 0x08,        # ..Report Size (8)                   48
        0x95, 0x01,        # ..Report Count (1)                  50
        0x09, 0x38,        # ..Usage (Wheel)                     52
        0x81, 0x06,        # ..Input (Data,Var,Rel)              54
        0x05, 0x0c,        # ..Usage Page (Consumer Devices)     56
        0x0a, 0x38, 0x02,  # ..Usage (AC Pan)                    58
        0x95, 0x01,        # ..Report Count (1)                  61
        0x81, 0x06,        # ..Input (Data,Var,Rel)              63
        0xc0,              # .End Collection                     65
        0xc0,              # End Collection                      66
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, input_info=None):
        super().__init__(rdesc, name, input_info)
        self.hwheel_multiplier = 1


class MIDongleMIWirelessMouse(TwoWheelMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,         # Usage Page (Generic Desktop)
        0x09, 0x02,         # Usage (Mouse)
        0xa1, 0x01,         # Collection (Application)
        0x85, 0x01,         # .Report ID (1)
        0x09, 0x01,         # .Usage (Pointer)
        0xa1, 0x00,         # .Collection (Physical)
        0x95, 0x05,         # ..Report Count (5)
        0x75, 0x01,         # ..Report Size (1)
        0x05, 0x09,         # ..Usage Page (Button)
        0x19, 0x01,         # ..Usage Minimum (1)
        0x29, 0x05,         # ..Usage Maximum (5)
        0x15, 0x00,         # ..Logical Minimum (0)
        0x25, 0x01,         # ..Logical Maximum (1)
        0x81, 0x02,         # ..Input (Data,Var,Abs)
        0x95, 0x01,         # ..Report Count (1)
        0x75, 0x03,         # ..Report Size (3)
        0x81, 0x01,         # ..Input (Cnst,Arr,Abs)
        0x75, 0x08,         # ..Report Size (8)
        0x95, 0x01,         # ..Report Count (1)
        0x05, 0x01,         # ..Usage Page (Generic Desktop)
        0x09, 0x38,         # ..Usage (Wheel)
        0x15, 0x81,         # ..Logical Minimum (-127)
        0x25, 0x7f,         # ..Logical Maximum (127)
        0x81, 0x06,         # ..Input (Data,Var,Rel)
        0x05, 0x0c,         # ..Usage Page (Consumer Devices)
        0x0a, 0x38, 0x02,   # ..Usage (AC Pan)
        0x95, 0x01,         # ..Report Count (1)
        0x81, 0x06,         # ..Input (Data,Var,Rel)
        0xc0,               # .End Collection
        0x85, 0x02,         # .Report ID (2)
        0x09, 0x01,         # .Usage (Consumer Control)
        0xa1, 0x00,         # .Collection (Physical)
        0x75, 0x0c,         # ..Report Size (12)
        0x95, 0x02,         # ..Report Count (2)
        0x05, 0x01,         # ..Usage Page (Generic Desktop)
        0x09, 0x30,         # ..Usage (X)
        0x09, 0x31,         # ..Usage (Y)
        0x16, 0x01, 0xf8,   # ..Logical Minimum (-2047)
        0x26, 0xff, 0x07,   # ..Logical Maximum (2047)
        0x81, 0x06,         # ..Input (Data,Var,Rel)
        0xc0,               # .End Collection
        0xc0,               # End Collection
        0x05, 0x0c,         # Usage Page (Consumer Devices)
        0x09, 0x01,         # Usage (Consumer Control)
        0xa1, 0x01,         # Collection (Application)
        0x85, 0x03,         # .Report ID (3)
        0x15, 0x00,         # .Logical Minimum (0)
        0x25, 0x01,         # .Logical Maximum (1)
        0x75, 0x01,         # .Report Size (1)
        0x95, 0x01,         # .Report Count (1)
        0x09, 0xcd,         # .Usage (Play/Pause)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x0a, 0x83, 0x01,   # .Usage (AL Consumer Control Config)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x09, 0xb5,         # .Usage (Scan Next Track)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x09, 0xb6,         # .Usage (Scan Previous Track)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x09, 0xea,         # .Usage (Volume Down)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x09, 0xe9,         # .Usage (Volume Up)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x0a, 0x25, 0x02,   # .Usage (AC Forward)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0x0a, 0x24, 0x02,   # .Usage (AC Back)
        0x81, 0x06,         # .Input (Data,Var,Rel)
        0xc0,               # End Collection
    ]
    # fmt: on
    device_input_info = (BusType.USB, 0x2717, 0x003B)
    device_name = "uhid test MI Dongle MI Wireless Mouse"

    def __init__(
        self, rdesc=report_descriptor, name=device_name, input_info=device_input_info
    ):
        super().__init__(rdesc, name, input_info)

    def event(self, x, y, buttons=None, wheels=None):
        # this mouse spreads the relative pointer and the mouse buttons
        # onto 2 distinct reports
        rs = []
        r = self.create_report(x, y, buttons, wheels, reportID=1)
        self.call_input_event(r)
        rs.append(r)
        r = self.create_report(x, y, buttons, reportID=2)
        self.call_input_event(r)
        rs.append(r)
        return rs


class ResolutionMultiplierMouse(TwoWheelMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,        # Usage Page (Generic Desktop)        83
        0x09, 0x02,        # Usage (Mouse)                       85
        0xa1, 0x01,        # Collection (Application)            87
        0x05, 0x01,        # .Usage Page (Generic Desktop)       89
        0x09, 0x02,        # .Usage (Mouse)                      91
        0xa1, 0x02,        # .Collection (Logical)               93
        0x85, 0x11,        # ..Report ID (17)                    95
        0x09, 0x01,        # ..Usage (Pointer)                   97
        0xa1, 0x00,        # ..Collection (Physical)             99
        0x05, 0x09,        # ...Usage Page (Button)              101
        0x19, 0x01,        # ...Usage Minimum (1)                103
        0x29, 0x03,        # ...Usage Maximum (3)                105
        0x95, 0x03,        # ...Report Count (3)                 107
        0x75, 0x01,        # ...Report Size (1)                  109
        0x25, 0x01,        # ...Logical Maximum (1)              111
        0x81, 0x02,        # ...Input (Data,Var,Abs)             113
        0x95, 0x01,        # ...Report Count (1)                 115
        0x81, 0x01,        # ...Input (Cnst,Arr,Abs)             117
        0x09, 0x05,        # ...Usage (Vendor Usage 0x05)        119
        0x81, 0x02,        # ...Input (Data,Var,Abs)             121
        0x95, 0x03,        # ...Report Count (3)                 123
        0x81, 0x01,        # ...Input (Cnst,Arr,Abs)             125
        0x05, 0x01,        # ...Usage Page (Generic Desktop)     127
        0x09, 0x30,        # ...Usage (X)                        129
        0x09, 0x31,        # ...Usage (Y)                        131
        0x95, 0x02,        # ...Report Count (2)                 133
        0x75, 0x08,        # ...Report Size (8)                  135
        0x15, 0x81,        # ...Logical Minimum (-127)           137
        0x25, 0x7f,        # ...Logical Maximum (127)            139
        0x81, 0x06,        # ...Input (Data,Var,Rel)             141
        0xa1, 0x02,        # ...Collection (Logical)             143
        0x85, 0x12,        # ....Report ID (18)                  145
        0x09, 0x48,        # ....Usage (Resolution Multiplier)   147
        0x95, 0x01,        # ....Report Count (1)                149
        0x75, 0x02,        # ....Report Size (2)                 151
        0x15, 0x00,        # ....Logical Minimum (0)             153
        0x25, 0x01,        # ....Logical Maximum (1)             155
        0x35, 0x01,        # ....Physical Minimum (1)            157
        0x45, 0x04,        # ....Physical Maximum (4)            159
        0xb1, 0x02,        # ....Feature (Data,Var,Abs)          161
        0x35, 0x00,        # ....Physical Minimum (0)            163
        0x45, 0x00,        # ....Physical Maximum (0)            165
        0x75, 0x06,        # ....Report Size (6)                 167
        0xb1, 0x01,        # ....Feature (Cnst,Arr,Abs)          169
        0x85, 0x11,        # ....Report ID (17)                  171
        0x09, 0x38,        # ....Usage (Wheel)                   173
        0x15, 0x81,        # ....Logical Minimum (-127)          175
        0x25, 0x7f,        # ....Logical Maximum (127)           177
        0x75, 0x08,        # ....Report Size (8)                 179
        0x81, 0x06,        # ....Input (Data,Var,Rel)            181
        0xc0,              # ...End Collection                   183
        0x05, 0x0c,        # ...Usage Page (Consumer Devices)    184
        0x75, 0x08,        # ...Report Size (8)                  186
        0x0a, 0x38, 0x02,  # ...Usage (AC Pan)                   188
        0x81, 0x06,        # ...Input (Data,Var,Rel)             191
        0xc0,              # ..End Collection                    193
        0xc0,              # .End Collection                     194
        0xc0,              # End Collection                      195
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, input_info=None):
        super().__init__(rdesc, name, input_info)
        self.default_reportID = 0x11

        # Feature Report 12, multiplier Feature value must be set to 0b01,
        # i.e. 1. We should extract that from the descriptor instead
        # of hardcoding it here, but meanwhile this will do.
        self.set_feature_report = [0x12, 0x1]

    def set_report(self, req, rnum, rtype, data):
        if rtype != self.UHID_FEATURE_REPORT:
            raise InvalidHIDCommunication(f"Unexpected report type: {rtype}")
        if rnum != 0x12:
            raise InvalidHIDCommunication(f"Unexpected report number: {rnum}")

        if data != self.set_feature_report:
            raise InvalidHIDCommunication(
                f"Unexpected data: {data}, expected {self.set_feature_report}"
            )

        self.wheel_multiplier = 4

        return 0


class BadResolutionMultiplierMouse(ResolutionMultiplierMouse):
    def set_report(self, req, rnum, rtype, data):
        super().set_report(req, rnum, rtype, data)

        self.wheel_multiplier = 1
        self.hwheel_multiplier = 1
        return 32  # EPIPE


class BadReportDescriptorMouse(BaseMouse):
    """
    This "device" was one autogenerated by syzbot. There are a lot of issues in
    it, and the most problematic is that it declares features that have no
    size.

    This leads to report->size being set to 0 and can mess up with usbhid
    internals.  Fortunately, uhid merely passes the incoming buffer, without
    touching it so a buffer of size 0 will be translated to [] without
    triggering a kernel oops.

    Because the report descriptor is wrong, no input are created, and we need
    to tweak a little bit the parameters to make it look correct.
    """

    # fmt: off
    report_descriptor = [
        0x96, 0x01, 0x00,              # Report Count (1)                    0
        0x06, 0x01, 0x00,              # Usage Page (Generic Desktop)        3
        # 0x03, 0x00, 0x00, 0x00, 0x00,  # Ignored by the kernel somehow
        0x2a, 0x90, 0xa0,              # Usage Maximum (41104)               6
        0x27, 0x00, 0x00, 0x00, 0x00,  # Logical Maximum (0)                 9
        0xb3, 0x81, 0x3e, 0x25, 0x03,  # Feature (Cnst,Arr,Abs,Vol)          14
        0x1b, 0xdd, 0xe8, 0x40, 0x50,  # Usage Minimum (1346431197)          19
        0x3b, 0x5d, 0x8c, 0x3d, 0xda,  # Designator Index                    24
    ]
    # fmt: on

    def __init__(
        self, rdesc=report_descriptor, name=None, input_info=(3, 0x045E, 0x07DA)
    ):
        super().__init__(rdesc, name, input_info)
        self.high_resolution_report_called = False

    def get_evdev(self, application=None):
        assert self._input_nodes is None
        return (
            "Ok"  # should be a list or None, but both would fail, so abusing the system
        )

    def next_sync_events(self, application=None):
        # there are no evdev nodes, so no events
        return []

    def is_ready(self):
        # we wait for the SET_REPORT command to come
        return self.high_resolution_report_called

    def set_report(self, req, rnum, rtype, data):
        if rtype != self.UHID_FEATURE_REPORT:
            raise InvalidHIDCommunication(f"Unexpected report type: {rtype}")
        if rnum != 0x0:
            raise InvalidHIDCommunication(f"Unexpected report number: {rnum}")

        if len(data) != 1:
            raise InvalidHIDCommunication(f"Unexpected data: {data}, expected '[0]'")

        self.high_resolution_report_called = True

        return 0


class ResolutionMultiplierHWheelMouse(TwoWheelMouse):
    # fmt: off
    report_descriptor = [
        0x05, 0x01,         # Usage Page (Generic Desktop)        0
        0x09, 0x02,         # Usage (Mouse)                       2
        0xa1, 0x01,         # Collection (Application)            4
        0x05, 0x01,         # .Usage Page (Generic Desktop)       6
        0x09, 0x02,         # .Usage (Mouse)                      8
        0xa1, 0x02,         # .Collection (Logical)               10
        0x85, 0x1a,         # ..Report ID (26)                    12
        0x09, 0x01,         # ..Usage (Pointer)                   14
        0xa1, 0x00,         # ..Collection (Physical)             16
        0x05, 0x09,         # ...Usage Page (Button)              18
        0x19, 0x01,         # ...Usage Minimum (1)                20
        0x29, 0x05,         # ...Usage Maximum (5)                22
        0x95, 0x05,         # ...Report Count (5)                 24
        0x75, 0x01,         # ...Report Size (1)                  26
        0x15, 0x00,         # ...Logical Minimum (0)              28
        0x25, 0x01,         # ...Logical Maximum (1)              30
        0x81, 0x02,         # ...Input (Data,Var,Abs)             32
        0x75, 0x03,         # ...Report Size (3)                  34
        0x95, 0x01,         # ...Report Count (1)                 36
        0x81, 0x01,         # ...Input (Cnst,Arr,Abs)             38
        0x05, 0x01,         # ...Usage Page (Generic Desktop)     40
        0x09, 0x30,         # ...Usage (X)                        42
        0x09, 0x31,         # ...Usage (Y)                        44
        0x95, 0x02,         # ...Report Count (2)                 46
        0x75, 0x10,         # ...Report Size (16)                 48
        0x16, 0x01, 0x80,   # ...Logical Minimum (-32767)         50
        0x26, 0xff, 0x7f,   # ...Logical Maximum (32767)          53
        0x81, 0x06,         # ...Input (Data,Var,Rel)             56
        0xa1, 0x02,         # ...Collection (Logical)             58
        0x85, 0x12,         # ....Report ID (18)                  60
        0x09, 0x48,         # ....Usage (Resolution Multiplier)   62
        0x95, 0x01,         # ....Report Count (1)                64
        0x75, 0x02,         # ....Report Size (2)                 66
        0x15, 0x00,         # ....Logical Minimum (0)             68
        0x25, 0x01,         # ....Logical Maximum (1)             70
        0x35, 0x01,         # ....Physical Minimum (1)            72
        0x45, 0x0c,         # ....Physical Maximum (12)           74
        0xb1, 0x02,         # ....Feature (Data,Var,Abs)          76
        0x85, 0x1a,         # ....Report ID (26)                  78
        0x09, 0x38,         # ....Usage (Wheel)                   80
        0x35, 0x00,         # ....Physical Minimum (0)            82
        0x45, 0x00,         # ....Physical Maximum (0)            84
        0x95, 0x01,         # ....Report Count (1)                86
        0x75, 0x10,         # ....Report Size (16)                88
        0x16, 0x01, 0x80,   # ....Logical Minimum (-32767)        90
        0x26, 0xff, 0x7f,   # ....Logical Maximum (32767)         93
        0x81, 0x06,         # ....Input (Data,Var,Rel)            96
        0xc0,               # ...End Collection                   98
        0xa1, 0x02,         # ...Collection (Logical)             99
        0x85, 0x12,         # ....Report ID (18)                  101
        0x09, 0x48,         # ....Usage (Resolution Multiplier)   103
        0x75, 0x02,         # ....Report Size (2)                 105
        0x15, 0x00,         # ....Logical Minimum (0)             107
        0x25, 0x01,         # ....Logical Maximum (1)             109
        0x35, 0x01,         # ....Physical Minimum (1)            111
        0x45, 0x0c,         # ....Physical Maximum (12)           113
        0xb1, 0x02,         # ....Feature (Data,Var,Abs)          115
        0x35, 0x00,         # ....Physical Minimum (0)            117
        0x45, 0x00,         # ....Physical Maximum (0)            119
        0x75, 0x04,         # ....Report Size (4)                 121
        0xb1, 0x01,         # ....Feature (Cnst,Arr,Abs)          123
        0x85, 0x1a,         # ....Report ID (26)                  125
        0x05, 0x0c,         # ....Usage Page (Consumer Devices)   127
        0x95, 0x01,         # ....Report Count (1)                129
        0x75, 0x10,         # ....Report Size (16)                131
        0x16, 0x01, 0x80,   # ....Logical Minimum (-32767)        133
        0x26, 0xff, 0x7f,   # ....Logical Maximum (32767)         136
        0x0a, 0x38, 0x02,   # ....Usage (AC Pan)                  139
        0x81, 0x06,         # ....Input (Data,Var,Rel)            142
        0xc0,               # ...End Collection                   144
        0xc0,               # ..End Collection                    145
        0xc0,               # .End Collection                     146
        0xc0,               # End Collection                      147
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, input_info=None):
        super().__init__(rdesc, name, input_info)
        self.default_reportID = 0x1A

        # Feature Report 12, multiplier Feature value must be set to 0b0101,
        # i.e. 5. We should extract that from the descriptor instead
        # of hardcoding it here, but meanwhile this will do.
        self.set_feature_report = [0x12, 0x5]

    def set_report(self, req, rnum, rtype, data):
        super().set_report(req, rnum, rtype, data)

        self.wheel_multiplier = 12
        self.hwheel_multiplier = 12

        return 0


class BaseTest:
    class TestMouse(base.BaseTestCase.TestUhid):
        def test_buttons(self):
            """check for button reliability."""
            uhdev = self.uhdev
            evdev = uhdev.get_evdev()
            syn_event = self.syn_event

            r = uhdev.event(0, 0, (None, True, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_RIGHT, 1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_RIGHT] == 1

            r = uhdev.event(0, 0, (None, False, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_RIGHT, 0)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_RIGHT] == 0

            r = uhdev.event(0, 0, (None, None, True))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_MIDDLE, 1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_MIDDLE] == 1

            r = uhdev.event(0, 0, (None, None, False))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_MIDDLE, 0)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_MIDDLE] == 0

            r = uhdev.event(0, 0, (True, None, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_LEFT] == 1

            r = uhdev.event(0, 0, (False, None, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_LEFT] == 0

            r = uhdev.event(0, 0, (True, True, None))
            expected_event0 = libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1)
            expected_event1 = libevdev.InputEvent(libevdev.EV_KEY.BTN_RIGHT, 1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn(
                (syn_event, expected_event0, expected_event1), events
            )
            assert evdev.value[libevdev.EV_KEY.BTN_RIGHT] == 1
            assert evdev.value[libevdev.EV_KEY.BTN_LEFT] == 1

            r = uhdev.event(0, 0, (False, None, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_RIGHT] == 1
            assert evdev.value[libevdev.EV_KEY.BTN_LEFT] == 0

            r = uhdev.event(0, 0, (None, False, None))
            expected_event = libevdev.InputEvent(libevdev.EV_KEY.BTN_RIGHT, 0)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEventsIn((syn_event, expected_event), events)
            assert evdev.value[libevdev.EV_KEY.BTN_RIGHT] == 0
            assert evdev.value[libevdev.EV_KEY.BTN_LEFT] == 0

        def test_relative(self):
            """Check for relative events."""
            uhdev = self.uhdev

            syn_event = self.syn_event

            r = uhdev.event(0, -1)
            expected_event = libevdev.InputEvent(libevdev.EV_REL.REL_Y, -1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEvents((syn_event, expected_event), events)

            r = uhdev.event(1, 0)
            expected_event = libevdev.InputEvent(libevdev.EV_REL.REL_X, 1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEvents((syn_event, expected_event), events)

            r = uhdev.event(-1, 2)
            expected_event0 = libevdev.InputEvent(libevdev.EV_REL.REL_X, -1)
            expected_event1 = libevdev.InputEvent(libevdev.EV_REL.REL_Y, 2)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEvents(
                (syn_event, expected_event0, expected_event1), events
            )


class TestSimpleMouse(BaseTest.TestMouse):
    def create_device(self):
        return ButtonMouse()

    def test_rdesc(self):
        """Check that the testsuite actually manages to format the
        reports according to the report descriptors.
        No kernel device is used here"""
        uhdev = self.uhdev

        event = (0, 0, (None, None, None))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (0, 0, (None, True, None))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (0, 0, (True, True, None))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (0, 0, (False, False, False))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (1, 0, (True, False, True))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (-1, 0, (True, False, True))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (-5, 5, (True, False, True))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (-127, 127, (True, False, True))
        assert uhdev.fake_report(*event) == uhdev.create_report(*event)

        event = (0, -128, (True, False, True))
        with pytest.raises(hidtools.hid.RangeError):
            uhdev.create_report(*event)


class TestWheelMouse(BaseTest.TestMouse):
    def create_device(self):
        return WheelMouse()

    def is_wheel_highres(self, uhdev):
        evdev = uhdev.get_evdev()
        assert evdev.has(libevdev.EV_REL.REL_WHEEL)
        return evdev.has(libevdev.EV_REL.REL_WHEEL_HI_RES)

    def test_wheel(self):
        uhdev = self.uhdev

        # check if the kernel is high res wheel compatible
        high_res_wheel = self.is_wheel_highres(uhdev)

        syn_event = self.syn_event
        # The Resolution Multiplier is applied to the HID reports, so we
        # need to pre-multiply too.
        mult = uhdev.wheel_multiplier

        r = uhdev.event(0, 0, wheels=1 * mult)
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL, 1))
        if high_res_wheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, 120))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(0, 0, wheels=-1 * mult)
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL, -1))
        if high_res_wheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, -120))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(-1, 2, wheels=3 * mult)
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_X, -1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_Y, 2))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL, 3))
        if high_res_wheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, 360))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)


class TestTwoWheelMouse(TestWheelMouse):
    def create_device(self):
        return TwoWheelMouse()

    def is_hwheel_highres(self, uhdev):
        evdev = uhdev.get_evdev()
        assert evdev.has(libevdev.EV_REL.REL_HWHEEL)
        return evdev.has(libevdev.EV_REL.REL_HWHEEL_HI_RES)

    def test_ac_pan(self):
        uhdev = self.uhdev

        # check if the kernel is high res wheel compatible
        high_res_wheel = self.is_wheel_highres(uhdev)
        high_res_hwheel = self.is_hwheel_highres(uhdev)
        assert high_res_wheel == high_res_hwheel

        syn_event = self.syn_event
        # The Resolution Multiplier is applied to the HID reports, so we
        # need to pre-multiply too.
        hmult = uhdev.hwheel_multiplier
        vmult = uhdev.wheel_multiplier

        r = uhdev.event(0, 0, wheels=(0, 1 * hmult))
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL, 1))
        if high_res_hwheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, 120))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(0, 0, wheels=(0, -1 * hmult))
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL, -1))
        if high_res_hwheel:
            expected.append(
                libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, -120)
            )
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(-1, 2, wheels=(0, 3 * hmult))
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_X, -1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_Y, 2))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL, 3))
        if high_res_hwheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, 360))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(-1, 2, wheels=(-3 * vmult, 4 * hmult))
        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_X, -1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_Y, 2))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL, -3))
        if high_res_wheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, -360))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL, 4))
        if high_res_wheel:
            expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, 480))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)


class TestResolutionMultiplierMouse(TestTwoWheelMouse):
    def create_device(self):
        return ResolutionMultiplierMouse()

    def is_wheel_highres(self, uhdev):
        high_res = super().is_wheel_highres(uhdev)

        if not high_res:
            # the kernel doesn't seem to support the high res wheel mice,
            # make sure we haven't triggered the feature
            assert uhdev.wheel_multiplier == 1

        return high_res

    def test_resolution_multiplier_wheel(self):
        uhdev = self.uhdev

        if not self.is_wheel_highres(uhdev):
            pytest.skip("Kernel not compatible, we can not trigger the conditions")

        assert uhdev.wheel_multiplier > 1
        assert 120 % uhdev.wheel_multiplier == 0

    def test_wheel_with_multiplier(self):
        uhdev = self.uhdev

        if not self.is_wheel_highres(uhdev):
            pytest.skip("Kernel not compatible, we can not trigger the conditions")

        assert uhdev.wheel_multiplier > 1

        syn_event = self.syn_event
        mult = uhdev.wheel_multiplier

        r = uhdev.event(0, 0, wheels=1)
        expected = [syn_event]
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, 120 / mult)
        )
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(0, 0, wheels=-1)
        expected = [syn_event]
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, -120 / mult)
        )
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_X, 1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_Y, -2))
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL_HI_RES, 120 / mult)
        )

        for _ in range(mult - 1):
            r = uhdev.event(1, -2, wheels=1)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEvents(expected, events)

        r = uhdev.event(1, -2, wheels=1)
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_WHEEL, 1))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)


class TestBadResolutionMultiplierMouse(TestTwoWheelMouse):
    def create_device(self):
        return BadResolutionMultiplierMouse()

    def is_wheel_highres(self, uhdev):
        high_res = super().is_wheel_highres(uhdev)

        assert uhdev.wheel_multiplier == 1

        return high_res

    def test_resolution_multiplier_wheel(self):
        uhdev = self.uhdev

        assert uhdev.wheel_multiplier == 1


class TestResolutionMultiplierHWheelMouse(TestResolutionMultiplierMouse):
    def create_device(self):
        return ResolutionMultiplierHWheelMouse()

    def is_hwheel_highres(self, uhdev):
        high_res = super().is_hwheel_highres(uhdev)

        if not high_res:
            # the kernel doesn't seem to support the high res wheel mice,
            # make sure we haven't triggered the feature
            assert uhdev.hwheel_multiplier == 1

        return high_res

    def test_resolution_multiplier_ac_pan(self):
        uhdev = self.uhdev

        if not self.is_hwheel_highres(uhdev):
            pytest.skip("Kernel not compatible, we can not trigger the conditions")

        assert uhdev.hwheel_multiplier > 1
        assert 120 % uhdev.hwheel_multiplier == 0

    def test_ac_pan_with_multiplier(self):
        uhdev = self.uhdev

        if not self.is_hwheel_highres(uhdev):
            pytest.skip("Kernel not compatible, we can not trigger the conditions")

        assert uhdev.hwheel_multiplier > 1

        syn_event = self.syn_event
        hmult = uhdev.hwheel_multiplier

        r = uhdev.event(0, 0, wheels=(0, 1))
        expected = [syn_event]
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, 120 / hmult)
        )
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        r = uhdev.event(0, 0, wheels=(0, -1))
        expected = [syn_event]
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, -120 / hmult)
        )
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)

        expected = [syn_event]
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_X, 1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_Y, -2))
        expected.append(
            libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL_HI_RES, 120 / hmult)
        )

        for _ in range(hmult - 1):
            r = uhdev.event(1, -2, wheels=(0, 1))
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)
            self.assertInputEvents(expected, events)

        r = uhdev.event(1, -2, wheels=(0, 1))
        expected.append(libevdev.InputEvent(libevdev.EV_REL.REL_HWHEEL, 1))
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        self.assertInputEvents(expected, events)


class TestMiMouse(TestWheelMouse):
    def create_device(self):
        return MIDongleMIWirelessMouse()

    def assertInputEvents(self, expected_events, effective_events):
        # Buttons and x/y are spread over two HID reports, so we can get two
        # event frames for this device.
        remaining = self.assertInputEventsIn(expected_events, effective_events)
        try:
            remaining.remove(libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0))
        except ValueError:
            # If there's no SYN_REPORT in the list, continue and let the
            # assert below print out the real error
            pass
        assert remaining == []


class TestBadReportDescriptorMouse(base.BaseTestCase.TestUhid):
    def create_device(self):
        return BadReportDescriptorMouse()

    def assertName(self, uhdev):
        pass
