#!/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.
# Copyright (c) 2020 Wacom Technology Corp.
#
# Authors:
#     Jason Gerecke <jason.gerecke@wacom.com>

"""
Tests for the Wacom driver generic codepath.

This module tests the function of the Wacom driver's generic codepath.
The generic codepath is used by devices which are not explicitly listed
in the driver's device table. It uses the device's HID descriptor to
decode reports sent by the device.
"""

from .descriptors_wacom import (
    wacom_pth660_v145,
    wacom_pth660_v150,
    wacom_pth860_v145,
    wacom_pth860_v150,
    wacom_pth460_v105,
)

import attr
from collections import namedtuple
from enum import Enum
from hidtools.hut import HUT
from hidtools.hid import HidUnit
from . import base
from . import test_multitouch
import libevdev
import pytest

import logging

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

KERNEL_MODULE = ("wacom", "wacom")


class ProximityState(Enum):
    """
    Enumeration of allowed proximity states.
    """

    # Tool is not able to be sensed by the device
    OUT = 0

    # Tool is close enough to be sensed, but some data may be invalid
    # or inaccurate
    IN_PROXIMITY = 1

    # Tool is close enough to be sensed with high accuracy. All data
    # valid.
    IN_RANGE = 2

    def fill(self, reportdata):
        """Fill a report with approrpiate HID properties/values."""
        reportdata.inrange = self in [ProximityState.IN_RANGE]
        reportdata.wacomsense = self in [
            ProximityState.IN_PROXIMITY,
            ProximityState.IN_RANGE,
        ]


class ReportData:
    """
    Placeholder for HID report values.
    """

    pass


@attr.s
class Buttons:
    """
    Stylus button state.

    Describes the state of each of the buttons / "side switches" that
    may be present on a stylus. Buttons set to 'None' indicate the
    state is "unchanged" since the previous event.
    """

    primary = attr.ib(default=None)
    secondary = attr.ib(default=None)
    tertiary = attr.ib(default=None)

    @staticmethod
    def clear():
        """Button object with all states cleared."""
        return Buttons(False, False, False)

    def fill(self, reportdata):
        """Fill a report with approrpiate HID properties/values."""
        reportdata.barrelswitch = int(self.primary or 0)
        reportdata.secondarybarrelswitch = int(self.secondary or 0)
        reportdata.b3 = int(self.tertiary or 0)


@attr.s
class ToolID:
    """
    Stylus tool identifiers.

    Contains values used to identify a specific stylus, e.g. its serial
    number and tool-type identifier. Values of ``0`` may sometimes be
    used for the out-of-range condition.
    """

    serial = attr.ib()
    tooltype = attr.ib()

    @staticmethod
    def clear():
        """ToolID object with all fields cleared."""
        return ToolID(0, 0)

    def fill(self, reportdata):
        """Fill a report with approrpiate HID properties/values."""
        reportdata.transducerserialnumber = self.serial & 0xFFFFFFFF
        reportdata.serialhi = (self.serial >> 32) & 0xFFFFFFFF
        reportdata.tooltype = self.tooltype


@attr.s
class PhysRange:
    """
    Range of HID physical values, with units.
    """

    unit = attr.ib()
    min_size = attr.ib()
    max_size = attr.ib()

    CENTIMETER = HidUnit.from_string("SILinear: cm")
    DEGREE = HidUnit.from_string("EnglishRotation: deg")

    def contains(self, field):
        """
        Check if the physical size of the provided field is in range.

        Compare the physical size described by the provided HID field
        against the range of sizes described by this object. This is
        an exclusive range comparison (e.g. 0 cm is not within the
        range 0 cm - 5 cm) and exact unit comparison (e.g. 1 inch is
        not within the range 0 cm - 5 cm).
        """
        phys_size = (field.physical_max - field.physical_min) * 10 ** (field.unit_exp)
        return (
            field.unit == self.unit.value
            and phys_size > self.min_size
            and phys_size < self.max_size
        )


class BaseTablet(base.UHIDTestDevice):
    """
    Skeleton object for all kinds of tablet devices.
    """

    def __init__(self, rdesc, name=None, info=None):
        assert rdesc is not None
        super().__init__(name, "Pen", input_info=info, rdesc=rdesc)
        self.buttons = Buttons.clear()
        self.toolid = ToolID.clear()
        self.proximity = ProximityState.OUT
        self.offset = 0
        self.ring = -1
        self.ek0 = False

    def match_evdev_rule(self, application, evdev):
        """
        Filter out evdev nodes based on the requested application.

        The Wacom driver may create several device nodes for each USB
        interface device. It is crucial that we run tests with the
        expected device node or things will obviously go off the rails.
        Use the Wacom driver's usual naming conventions to apply a
        sensible default filter.
        """
        if application in ["Pen", "Pad"]:
            return evdev.name.endswith(application)
        else:
            return True

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

        :param x: absolute x
        :param y: absolute y
        :param pressure: pressure
        :param buttons: stylus button state. Use ``None`` for unchanged.
        :param toolid: tool identifiers. Use ``None`` for unchanged.
        :param proximity: a ProximityState indicating the sensor's ability
             to detect and report attributes of this tool. Use ``None``
             for unchanged.
        :param reportID: the numeric report ID for this report, if needed
        """
        if buttons is not None:
            self.buttons = buttons
        buttons = self.buttons

        if toolid is not None:
            self.toolid = toolid
        toolid = self.toolid

        if proximity is not None:
            self.proximity = proximity
        proximity = self.proximity

        reportID = reportID or self.default_reportID

        report = ReportData()
        report.x = x
        report.y = y
        report.tippressure = pressure
        report.tipswitch = pressure > 0
        buttons.fill(report)
        proximity.fill(report)
        toolid.fill(report)

        return super().create_report(report, reportID=reportID)

    def create_report_heartbeat(self, reportID):
        """
        Return a heartbeat input report for this device.

        Heartbeat reports generally contain battery status information,
        among other things.
        """
        report = ReportData()
        report.wacombatterycharging = 1
        return super().create_report(report, reportID=reportID)

    def create_report_pad(self, reportID, ring, ek0):
        report = ReportData()

        if ring is not None:
            self.ring = ring
        ring = self.ring

        if ek0 is not None:
            self.ek0 = ek0
        ek0 = self.ek0

        if ring >= 0:
            report.wacomtouchring = ring
            report.wacomtouchringstatus = 1
        else:
            report.wacomtouchring = 0x7F
            report.wacomtouchringstatus = 0

        report.wacomexpresskey00 = ek0
        return super().create_report(report, reportID=reportID)

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

        :param x: absolute x
        :param y: absolute y
        :param buttons: stylus button state. Use ``None`` for unchanged.
        :param toolid: tool identifiers. Use ``None`` for unchanged.
        :param proximity: a ProximityState indicating the sensor's ability
             to detect and report attributes of this tool. Use ``None``
             for unchanged.
        """
        r = self.create_report(x, y, pressure, buttons, toolid, proximity)
        self.call_input_event(r)
        return [r]

    def event_heartbeat(self, reportID):
        """
        Send a heartbeat event on the requested report ID.
        """
        r = self.create_report_heartbeat(reportID)
        self.call_input_event(r)
        return [r]

    def event_pad(self, reportID, ring=None, ek0=None):
        """
        Send a pad event on the requested report ID.
        """
        r = self.create_report_pad(reportID, ring, ek0)
        self.call_input_event(r)
        return [r]

    def get_report(self, req, rnum, rtype):
        if rtype != self.UHID_FEATURE_REPORT:
            return (1, [])

        rdesc = None
        for v in self.parsed_rdesc.feature_reports.values():
            if v.report_ID == rnum:
                rdesc = v

        if rdesc is None:
            return (1, [])

        result = (1, [])
        result = self.create_report_offset(rdesc) or result
        return result

    def create_report_offset(self, rdesc):
        require = [
            "Wacom Offset Left",
            "Wacom Offset Top",
            "Wacom Offset Right",
            "Wacom Offset Bottom",
        ]
        if not set(require).issubset(set([f.usage_name for f in rdesc])):
            return None

        report = ReportData()
        report.wacomoffsetleft = self.offset
        report.wacomoffsettop = self.offset
        report.wacomoffsetright = self.offset
        report.wacomoffsetbottom = self.offset
        r = rdesc.create_report([report], None)
        return (0, r)


class OpaqueTablet(BaseTablet):
    """
    Bare-bones opaque tablet with a minimum of features.

    A tablet stripped down to its absolute core. It is capable of
    reporting X/Y position and if the pen is in contact. No pressure,
    no barrel switches, no eraser. Notably it *does* report an "In
    Range" flag, but this is only because the Wacom driver expects
    one to function properly. The device uses only standard HID usages,
    not any of Wacom's vendor-defined pages.
    """

    # fmt: off
    report_descriptor = [
        0x05, 0x0D,                     # . Usage Page (Digitizer),
        0x09, 0x01,                     # . Usage (Digitizer),
        0xA1, 0x01,                     # . Collection (Application),
        0x85, 0x01,                     # .     Report ID (1),
        0x09, 0x20,                     # .     Usage (Stylus),
        0xA1, 0x00,                     # .     Collection (Physical),
        0x09, 0x42,                     # .         Usage (Tip Switch),
        0x09, 0x32,                     # .         Usage (In Range),
        0x15, 0x00,                     # .         Logical Minimum (0),
        0x25, 0x01,                     # .         Logical Maximum (1),
        0x75, 0x01,                     # .         Report Size (1),
        0x95, 0x02,                     # .         Report Count (2),
        0x81, 0x02,                     # .         Input (Variable),
        0x95, 0x06,                     # .         Report Count (6),
        0x81, 0x03,                     # .         Input (Constant, Variable),
        0x05, 0x01,                     # .         Usage Page (Desktop),
        0x09, 0x30,                     # .         Usage (X),
        0x27, 0x80, 0x3E, 0x00, 0x00,   # .         Logical Maximum (16000),
        0x47, 0x80, 0x3E, 0x00, 0x00,   # .         Physical Maximum (16000),
        0x65, 0x11,                     # .         Unit (Centimeter),
        0x55, 0x0D,                     # .         Unit Exponent (13),
        0x75, 0x10,                     # .         Report Size (16),
        0x95, 0x01,                     # .         Report Count (1),
        0x81, 0x02,                     # .         Input (Variable),
        0x09, 0x31,                     # .         Usage (Y),
        0x27, 0x28, 0x23, 0x00, 0x00,   # .         Logical Maximum (9000),
        0x47, 0x28, 0x23, 0x00, 0x00,   # .         Physical Maximum (9000),
        0x81, 0x02,                     # .         Input (Variable),
        0xC0,                           # .     End Collection,
        0xC0,                           # . End Collection,
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, info=(0x3, 0x056A, 0x9999)):
        super().__init__(rdesc, name, info)
        self.default_reportID = 1


class OpaqueCTLTablet(BaseTablet):
    """
    Opaque tablet similar to something in the CTL product line.

    A pen-only tablet with most basic features you would expect from
    an actual device. Position, eraser, pressure, barrel buttons.
    Uses the Wacom vendor-defined usage page.
    """

    # fmt: off
    report_descriptor = [
        0x06, 0x0D, 0xFF,               # . Usage Page (Vnd Wacom Emr),
        0x09, 0x01,                     # . Usage (Digitizer),
        0xA1, 0x01,                     # . Collection (Application),
        0x85, 0x10,                     # .     Report ID (16),
        0x09, 0x20,                     # .     Usage (Stylus),
        0x35, 0x00,                     # .     Physical Minimum (0),
        0x45, 0x00,                     # .     Physical Maximum (0),
        0x15, 0x00,                     # .     Logical Minimum (0),
        0x25, 0x01,                     # .     Logical Maximum (1),
        0xA1, 0x00,                     # .     Collection (Physical),
        0x09, 0x42,                     # .         Usage (Tip Switch),
        0x09, 0x44,                     # .         Usage (Barrel Switch),
        0x09, 0x5A,                     # .         Usage (Secondary Barrel Switch),
        0x09, 0x45,                     # .         Usage (Eraser),
        0x09, 0x3C,                     # .         Usage (Invert),
        0x09, 0x32,                     # .         Usage (In Range),
        0x09, 0x36,                     # .         Usage (In Proximity),
        0x25, 0x01,                     # .         Logical Maximum (1),
        0x75, 0x01,                     # .         Report Size (1),
        0x95, 0x07,                     # .         Report Count (7),
        0x81, 0x02,                     # .         Input (Variable),
        0x95, 0x01,                     # .         Report Count (1),
        0x81, 0x03,                     # .         Input (Constant, Variable),
        0x0A, 0x30, 0x01,               # .         Usage (X),
        0x65, 0x11,                     # .         Unit (Centimeter),
        0x55, 0x0D,                     # .         Unit Exponent (13),
        0x47, 0x80, 0x3E, 0x00, 0x00,   # .         Physical Maximum (16000),
        0x27, 0x80, 0x3E, 0x00, 0x00,   # .         Logical Maximum (16000),
        0x75, 0x18,                     # .         Report Size (24),
        0x95, 0x01,                     # .         Report Count (1),
        0x81, 0x02,                     # .         Input (Variable),
        0x0A, 0x31, 0x01,               # .         Usage (Y),
        0x47, 0x28, 0x23, 0x00, 0x00,   # .         Physical Maximum (9000),
        0x27, 0x28, 0x23, 0x00, 0x00,   # .         Logical Maximum (9000),
        0x81, 0x02,                     # .         Input (Variable),
        0x09, 0x30,                     # .         Usage (Tip Pressure),
        0x55, 0x00,                     # .         Unit Exponent (0),
        0x65, 0x00,                     # .         Unit,
        0x47, 0x00, 0x00, 0x00, 0x00,   # .         Physical Maximum (0),
        0x26, 0xFF, 0x0F,               # .         Logical Maximum (4095),
        0x75, 0x10,                     # .         Report Size (16),
        0x81, 0x02,                     # .         Input (Variable),
        0x75, 0x08,                     # .         Report Size (8),
        0x95, 0x06,                     # .         Report Count (6),
        0x81, 0x03,                     # .         Input (Constant, Variable),
        0x0A, 0x32, 0x01,               # .         Usage (Z),
        0x25, 0x3F,                     # .         Logical Maximum (63),
        0x75, 0x08,                     # .         Report Size (8),
        0x95, 0x01,                     # .         Report Count (1),
        0x81, 0x02,                     # .         Input (Variable),
        0x09, 0x5B,                     # .         Usage (Transducer Serial Number),
        0x09, 0x5C,                     # .         Usage (Transducer Serial Number Hi),
        0x17, 0x00, 0x00, 0x00, 0x80,   # .         Logical Minimum (-2147483648),
        0x27, 0xFF, 0xFF, 0xFF, 0x7F,   # .         Logical Maximum (2147483647),
        0x75, 0x20,                     # .         Report Size (32),
        0x95, 0x02,                     # .         Report Count (2),
        0x81, 0x02,                     # .         Input (Variable),
        0x09, 0x77,                     # .         Usage (Tool Type),
        0x15, 0x00,                     # .         Logical Minimum (0),
        0x26, 0xFF, 0x0F,               # .         Logical Maximum (4095),
        0x75, 0x10,                     # .         Report Size (16),
        0x95, 0x01,                     # .         Report Count (1),
        0x81, 0x02,                     # .         Input (Variable),
        0xC0,                           # .     End Collection,
        0xC0                            # . End Collection
    ]
    # fmt: on

    def __init__(self, rdesc=report_descriptor, name=None, info=(0x3, 0x056A, 0x9999)):
        super().__init__(rdesc, name, info)
        self.default_reportID = 16


class PTHX60_Pen(BaseTablet):
    """
    Pen interface of a PTH-660 / PTH-860 / PTH-460 tablet.

    This generation of devices are nearly identical to each other, though
    the PTH-460 uses a slightly different descriptor construction (splits
    the pad among several physical collections)
    """

    def __init__(self, rdesc=None, name=None, info=None):
        super().__init__(rdesc, name, info)
        self.default_reportID = 16


class BaseTest:
    class TestTablet(base.BaseTestCase.TestUhid):
        kernel_modules = [KERNEL_MODULE]

        def sync_and_assert_events(
            self, report, expected_events, auto_syn=True, strict=False
        ):
            """
            Assert we see the expected events in response to a report.
            """
            uhdev = self.uhdev
            syn_event = self.syn_event
            if auto_syn:
                expected_events.append(syn_event)
            actual_events = uhdev.next_sync_events()
            self.debug_reports(report, uhdev, actual_events)
            if strict:
                self.assertInputEvents(expected_events, actual_events)
            else:
                self.assertInputEventsIn(expected_events, actual_events)

        def get_usages(self, uhdev):
            def get_report_usages(report):
                application = report.application
                for field in report.fields:
                    if field.usages is not None:
                        for usage in field.usages:
                            yield (field, usage, application)
                    else:
                        yield (field, field.usage, application)

            desc = uhdev.parsed_rdesc
            reports = [
                *desc.input_reports.values(),
                *desc.feature_reports.values(),
                *desc.output_reports.values(),
            ]
            for report in reports:
                for usage in get_report_usages(report):
                    yield usage

        def assertName(self, uhdev, type):
            """
            Assert that the name is as we expect.

            The Wacom driver applies a number of decorations to the name
            provided by the hardware. We cannot rely on the definition of
            this assertion from the base class to work properly.
            """
            evdev = uhdev.get_evdev()
            expected_name = uhdev.name + type
            if "wacom" not in expected_name.lower():
                expected_name = "Wacom " + expected_name
            assert evdev.name == expected_name

        def test_descriptor_physicals(self):
            """
            Verify that all HID usages which should have a physical range
            actually do, and those which shouldn't don't. Also verify that
            the associated unit is correct and within a sensible range.
            """

            def usage_id(page_name, usage_name):
                page = HUT.usage_page_from_name(page_name)
                return (page.page_id << 16) | page[usage_name].usage

            required = {
                usage_id("Generic Desktop", "X"): PhysRange(
                    PhysRange.CENTIMETER, 5, 150
                ),
                usage_id("Generic Desktop", "Y"): PhysRange(
                    PhysRange.CENTIMETER, 5, 150
                ),
                usage_id("Digitizers", "Width"): PhysRange(
                    PhysRange.CENTIMETER, 5, 150
                ),
                usage_id("Digitizers", "Height"): PhysRange(
                    PhysRange.CENTIMETER, 5, 150
                ),
                usage_id("Digitizers", "X Tilt"): PhysRange(PhysRange.DEGREE, 90, 180),
                usage_id("Digitizers", "Y Tilt"): PhysRange(PhysRange.DEGREE, 90, 180),
                usage_id("Digitizers", "Twist"): PhysRange(PhysRange.DEGREE, 358, 360),
                usage_id("Wacom", "X Tilt"): PhysRange(PhysRange.DEGREE, 90, 180),
                usage_id("Wacom", "Y Tilt"): PhysRange(PhysRange.DEGREE, 90, 180),
                usage_id("Wacom", "Twist"): PhysRange(PhysRange.DEGREE, 358, 360),
                usage_id("Wacom", "X"): PhysRange(PhysRange.CENTIMETER, 5, 150),
                usage_id("Wacom", "Y"): PhysRange(PhysRange.CENTIMETER, 5, 150),
                usage_id("Wacom", "Wacom TouchRing"): PhysRange(
                    PhysRange.DEGREE, 358, 360
                ),
                usage_id("Wacom", "Wacom Offset Left"): PhysRange(
                    PhysRange.CENTIMETER, 0, 0.5
                ),
                usage_id("Wacom", "Wacom Offset Top"): PhysRange(
                    PhysRange.CENTIMETER, 0, 0.5
                ),
                usage_id("Wacom", "Wacom Offset Right"): PhysRange(
                    PhysRange.CENTIMETER, 0, 0.5
                ),
                usage_id("Wacom", "Wacom Offset Bottom"): PhysRange(
                    PhysRange.CENTIMETER, 0, 0.5
                ),
            }
            for field, usage, application in self.get_usages(self.uhdev):
                if application == usage_id("Generic Desktop", "Mouse"):
                    # Ignore the vestigial Mouse collection which exists
                    # on Wacom tablets only for backwards compatibility.
                    continue

                expect_physical = usage in required

                phys_set = field.physical_min != 0 or field.physical_max != 0
                assert phys_set == expect_physical

                unit_set = field.unit != 0
                assert unit_set == expect_physical

                if unit_set:
                    assert required[usage].contains(field)

        def test_prop_direct(self):
            """
            Todo: Verify that INPUT_PROP_DIRECT is set on display devices.
            """
            pass

        def test_prop_pointer(self):
            """
            Todo: Verify that INPUT_PROP_POINTER is set on opaque devices.
            """
            pass


class PenTabletTest(BaseTest.TestTablet):
    def assertName(self, uhdev):
        super().assertName(uhdev, " Pen")


class TouchTabletTest(BaseTest.TestTablet):
    def assertName(self, uhdev):
        super().assertName(uhdev, " Finger")


class TestOpaqueTablet(PenTabletTest):
    def create_device(self):
        return OpaqueTablet()

    def test_sanity(self):
        """
        Bring a pen into contact with the tablet, then remove it.

        Ensure that we get the basic tool/touch/motion events that should
        be sent by the driver.
        """
        uhdev = self.uhdev

        self.sync_and_assert_events(
            uhdev.event(
                100,
                200,
                pressure=300,
                buttons=Buttons.clear(),
                toolid=ToolID(serial=1, tooltype=1),
                proximity=ProximityState.IN_RANGE,
            ),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 100),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 200),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(110, 220, pressure=0),
            [
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 110),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 220),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(
                120,
                230,
                pressure=0,
                toolid=ToolID.clear(),
                proximity=ProximityState.OUT,
            ),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(130, 240, pressure=0), [], auto_syn=False, strict=True
        )


class TestOpaqueCTLTablet(TestOpaqueTablet):
    def create_device(self):
        return OpaqueCTLTablet()

    def test_buttons(self):
        """
        Test that the barrel buttons (side switches) work as expected.

        Press and release each button individually to verify that we get
        the expected events.
        """
        uhdev = self.uhdev

        self.sync_and_assert_events(
            uhdev.event(
                100,
                200,
                pressure=0,
                buttons=Buttons.clear(),
                toolid=ToolID(serial=1, tooltype=1),
                proximity=ProximityState.IN_RANGE,
            ),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 100),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 200),
                libevdev.InputEvent(libevdev.EV_MSC.MSC_SERIAL, 1),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(100, 200, pressure=0, buttons=Buttons(primary=True)),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1),
                libevdev.InputEvent(libevdev.EV_MSC.MSC_SERIAL, 1),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(100, 200, pressure=0, buttons=Buttons(primary=False)),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0),
                libevdev.InputEvent(libevdev.EV_MSC.MSC_SERIAL, 1),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(100, 200, pressure=0, buttons=Buttons(secondary=True)),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2, 1),
                libevdev.InputEvent(libevdev.EV_MSC.MSC_SERIAL, 1),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event(100, 200, pressure=0, buttons=Buttons(secondary=False)),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2, 0),
                libevdev.InputEvent(libevdev.EV_MSC.MSC_SERIAL, 1),
            ],
        )


PTHX60_Devices = [
    {"rdesc": wacom_pth660_v145, "info": (0x3, 0x056A, 0x0357)},
    {"rdesc": wacom_pth660_v150, "info": (0x3, 0x056A, 0x0357)},
    {"rdesc": wacom_pth860_v145, "info": (0x3, 0x056A, 0x0358)},
    {"rdesc": wacom_pth860_v150, "info": (0x3, 0x056A, 0x0358)},
    {"rdesc": wacom_pth460_v105, "info": (0x3, 0x056A, 0x0392)},
]

PTHX60_Names = [
    "PTH-660/v145",
    "PTH-660/v150",
    "PTH-860/v145",
    "PTH-860/v150",
    "PTH-460/v105",
]


class TestPTHX60_Pen(TestOpaqueCTLTablet):
    @pytest.fixture(
        autouse=True, scope="class", params=PTHX60_Devices, ids=PTHX60_Names
    )
    def set_device_params(self, request):
        request.cls.device_params = request.param

    def create_device(self):
        return PTHX60_Pen(**self.device_params)

    @pytest.mark.xfail
    def test_descriptor_physicals(self):
        # XFAIL: Various documented errata
        super().test_descriptor_physicals()

    def test_heartbeat_spurious(self):
        """
        Test that the heartbeat report does not send spurious events.
        """
        uhdev = self.uhdev

        self.sync_and_assert_events(
            uhdev.event(
                100,
                200,
                pressure=300,
                buttons=Buttons.clear(),
                toolid=ToolID(serial=1, tooltype=0x822),
                proximity=ProximityState.IN_RANGE,
            ),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 100),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 200),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1),
            ],
        )

        # Exactly zero events: not even a SYN
        self.sync_and_assert_events(
            uhdev.event_heartbeat(19), [], auto_syn=False, strict=True
        )

        self.sync_and_assert_events(
            uhdev.event(110, 200, pressure=300),
            [
                libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 110),
            ],
        )

    def test_empty_pad_sync(self):
        self.empty_pad_sync(num=3, denom=16, reverse=True)

    def empty_pad_sync(self, num, denom, reverse):
        """
        Test that multiple pad collections do not trigger empty syncs.
        """

        def offset_rotation(value):
            """
            Offset touchring rotation values by the same factor as the
            Linux kernel. Tablets historically don't use the same origin
            as HID, and it sometimes changes from tablet to tablet...
            """
            evdev = self.uhdev.get_evdev()
            info = evdev.absinfo[libevdev.EV_ABS.ABS_WHEEL]
            delta = info.maximum - info.minimum + 1
            if reverse:
                value = info.maximum - value
            value += num * delta // denom
            if value > info.maximum:
                value -= delta
            elif value < info.minimum:
                value += delta
            return value

        uhdev = self.uhdev
        uhdev.application = "Pad"
        evdev = uhdev.get_evdev()

        print(evdev.name)
        self.sync_and_assert_events(
            uhdev.event_pad(reportID=17, ring=0, ek0=1),
            [
                libevdev.InputEvent(libevdev.EV_KEY.BTN_0, 1),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_WHEEL, offset_rotation(0)),
                libevdev.InputEvent(libevdev.EV_ABS.ABS_MISC, 15),
            ],
        )

        self.sync_and_assert_events(
            uhdev.event_pad(reportID=17, ring=1, ek0=1),
            [libevdev.InputEvent(libevdev.EV_ABS.ABS_WHEEL, offset_rotation(1))],
        )

        self.sync_and_assert_events(
            uhdev.event_pad(reportID=17, ring=2, ek0=0),
            [
                libevdev.InputEvent(libevdev.EV_ABS.ABS_WHEEL, offset_rotation(2)),
                libevdev.InputEvent(libevdev.EV_KEY.BTN_0, 0),
            ],
        )


class TestDTH2452Tablet(test_multitouch.BaseTest.TestMultitouch, TouchTabletTest):
    ContactIds = namedtuple("ContactIds", "contact_id, tracking_id, slot_num")

    def create_device(self):
        return test_multitouch.Digitizer(
            "DTH 2452",
            rdesc="05 0d 09 04 a1 01 85 0c 95 01 75 08 15 00 26 ff 00 81 03 09 54 81 02 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 09 22 a1 02 05 0d 95 01 75 01 25 01 09 42 81 02 81 03 09 47 81 02 95 05 81 03 09 51 26 ff 00 75 10 95 01 81 02 35 00 65 11 55 0e 05 01 09 30 26 a0 44 46 96 14 81 42 09 31 26 9a 26 46 95 0b 81 42 05 0d 75 08 95 01 15 00 09 48 26 5f 00 46 7c 14 81 02 09 49 25 35 46 7d 0b 81 02 45 00 65 00 55 00 c0 05 0d 27 ff ff 00 00 75 10 95 01 09 56 81 02 75 08 95 0e 81 03 09 55 26 ff 00 75 08 b1 02 85 0a 06 00 ff 09 c5 96 00 01 b1 02 c0 06 00 ff 09 01 a1 01 09 01 85 13 15 00 26 ff 00 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0",
            input_info=(0x3, 0x056A, 0x0383),
        )

    def make_contact(self, contact_id=0, t=0):
        """
        Make a single touch contact that can move over time.

        Creates a touch object that has a well-known position in space that
        does not overlap with other contacts. The value of `t` may be
        incremented over time to move the point along a linear path.
        """
        x = 50 + 10 * contact_id + t * 11
        y = 100 + 100 * contact_id + t * 11
        return test_multitouch.Touch(contact_id, x, y)

    def make_contacts(self, n, t=0):
        """
        Make multiple touch contacts that can move over time.

        Returns a list of `n` touch objects that are positioned at well-known
        locations. The value of `t` may be incremented over time to move the
        points along a linear path.
        """
        return [ self.make_contact(id, t) for id in range(0, n) ]

    def assert_contact(self, uhdev, evdev, contact_ids, t=0):
        """
        Assert properties of a contact generated by make_contact.
        """
        contact_id = contact_ids.contact_id
        tracking_id = contact_ids.tracking_id
        slot_num = contact_ids.slot_num

        x = 50 + 10 * contact_id + t * 11
        y = 100 + 100 * contact_id + t * 11

        # If the data isn't supposed to be stored in any slots, there is
        # nothing we can check for in the evdev stream.
        if slot_num is None:
            assert tracking_id == -1
            return

        assert evdev.slots[slot_num][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == tracking_id
        if tracking_id != -1:
            assert evdev.slots[slot_num][libevdev.EV_ABS.ABS_MT_POSITION_X] == x
            assert evdev.slots[slot_num][libevdev.EV_ABS.ABS_MT_POSITION_Y] == y

    def assert_contacts(self, uhdev, evdev, data, t=0):
        """
        Assert properties of a list of contacts generated by make_contacts.
        """
        for contact_ids in data:
            self.assert_contact(uhdev, evdev, contact_ids, t)

    def test_contact_id_0(self):
        """
        Bring a finger in contact with the tablet, then hold it down and remove it.

        Ensure that even with contact ID = 0 which is usually given as an invalid
        touch event by most tablets with the exception of a few, that given the
        confidence bit is set to 1 it should process it as a valid touch to cover
        the few tablets using contact ID = 0 as a valid touch value.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        t0 = test_multitouch.Touch(0, 50, 100)
        r = uhdev.event([t0])
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)

        slot = self.get_slot(uhdev, t0, 0)

        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events
        assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == 0
        assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_POSITION_X] == 50
        assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_POSITION_Y] == 100

        t0.tipswitch = False
        if uhdev.quirks is None or "VALID_IS_INRANGE" not in uhdev.quirks:
            t0.inrange = False
        r = uhdev.event([t0])
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)
        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in events
        assert evdev.slots[slot][libevdev.EV_ABS.ABS_MT_TRACKING_ID] == -1

    def test_confidence_false(self):
        """
        Bring a finger in contact with the tablet with confidence set to false.

        Ensure that the confidence bit being set to false should not result in a touch event.
        """
        uhdev = self.uhdev
        _evdev = uhdev.get_evdev()

        t0 = test_multitouch.Touch(1, 50, 100)
        t0.confidence = False
        r = uhdev.event([t0])
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)

        _slot = self.get_slot(uhdev, t0, 0)

        assert not events

    def test_confidence_multitouch(self):
        """
        Bring multiple fingers in contact with the tablet, some with the
        confidence bit set, and some without.

        Ensure that all confident touches are reported and that all non-
        confident touches are ignored.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        touches = self.make_contacts(5)
        touches[0].confidence = False
        touches[2].confidence = False
        touches[4].confidence = False

        r = uhdev.event(touches)
        events = uhdev.next_sync_events()
        self.debug_reports(r, uhdev, events)

        assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events

        self.assert_contacts(uhdev, evdev,
            [ self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = None),
              self.ContactIds(contact_id = 1, tracking_id = 0, slot_num = 0),
              self.ContactIds(contact_id = 2, tracking_id = -1, slot_num = None),
              self.ContactIds(contact_id = 3, tracking_id = 1, slot_num = 1),
              self.ContactIds(contact_id = 4, tracking_id = -1, slot_num = None) ])

    def confidence_change_assert_playback(self, uhdev, evdev, timeline):
        """
        Assert proper behavior of contacts that move and change tipswitch /
        confidence status over time.

        Given a `timeline` list of touch states to iterate over, verify
        that the contacts move and are reported as up/down as expected
        by the state of the tipswitch and confidence bits.
        """
        t = 0

        for state in timeline:
            touches = self.make_contacts(len(state), t)

            for item in zip(touches, state):
                item[0].tipswitch = item[1][1]
                item[0].confidence = item[1][2]

            r = uhdev.event(touches)
            events = uhdev.next_sync_events()
            self.debug_reports(r, uhdev, events)

            ids = [ x[0] for x in state ]
            self.assert_contacts(uhdev, evdev, ids, t)

            t += 1

    def test_confidence_loss_a(self):
        """
        Transition a confident contact to a non-confident contact by
        first clearing the tipswitch.

        Ensure that the driver reports the transitioned contact as
        being removed and that other contacts continue to report
        normally. This mode of confidence loss is used by the
        DTH-2452.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        self.confidence_change_assert_playback(uhdev, evdev, [
            # t=0: Contact 0 == Down + confident; Contact 1 == Down + confident
            # Both fingers confidently in contact
            [(self.ContactIds(contact_id = 0, tracking_id = 0, slot_num = 0), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=1: Contact 0 == !Down + confident; Contact 1 == Down + confident
            # First finger looses confidence and clears only the tipswitch flag
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=2: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=3: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)]
        ])

    def test_confidence_loss_b(self):
        """
        Transition a confident contact to a non-confident contact by
        cleraing both tipswitch and confidence bits simultaneously.

        Ensure that the driver reports the transitioned contact as
        being removed and that other contacts continue to report
        normally. This mode of confidence loss is used by some
        AES devices.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        self.confidence_change_assert_playback(uhdev, evdev, [
            # t=0: Contact 0 == Down + confident; Contact 1 == Down + confident
            # Both fingers confidently in contact
            [(self.ContactIds(contact_id = 0, tracking_id = 0, slot_num = 0), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=1: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger looses confidence and has both flags cleared simultaneously
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=2: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=3: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)]
        ])

    def test_confidence_loss_c(self):
        """
        Transition a confident contact to a non-confident contact by
        clearing only the confidence bit.

        Ensure that the driver reports the transitioned contact as
        being removed and that other contacts continue to report
        normally.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        self.confidence_change_assert_playback(uhdev, evdev, [
            # t=0: Contact 0 == Down + confident; Contact 1 == Down + confident
            # Both fingers confidently in contact
            [(self.ContactIds(contact_id = 0, tracking_id = 0, slot_num = 0), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=1: Contact 0 == Down + !confident; Contact 1 == Down + confident
            # First finger looses confidence and clears only the confidence flag
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), True, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=2: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=3: Contact 0 == !Down + !confident; Contact 1 == Down + confident
            # First finger has lost confidence and has both flags cleared
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)]
        ])

    def test_confidence_gain_a(self):
        """
        Transition a contact that was always non-confident to confident.

        Ensure that the confident contact is reported normally.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        self.confidence_change_assert_playback(uhdev, evdev, [
            # t=0: Contact 0 == Down + !confident; Contact 1 == Down + confident
            # Only second finger is confidently in contact
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = None), True, False),
             (self.ContactIds(contact_id = 1, tracking_id = 0, slot_num = 0), True, True)],

            # t=1: Contact 0 == Down + !confident; Contact 1 == Down + confident
            # First finger gains confidence
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = None), True, False),
             (self.ContactIds(contact_id = 1, tracking_id = 0, slot_num = 0), True, True)],

            # t=2: Contact 0 == Down + confident; Contact 1 == Down + confident
            # First finger remains confident
            [(self.ContactIds(contact_id = 0, tracking_id = 1, slot_num = 1), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 0, slot_num = 0), True, True)],

            # t=3: Contact 0 == Down + confident; Contact 1 == Down + confident
            # First finger remains confident
            [(self.ContactIds(contact_id = 0, tracking_id = 1, slot_num = 1), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 0, slot_num = 0), True, True)]
        ])

    def test_confidence_gain_b(self):
        """
        Transition a contact from non-confident to confident.

        Ensure that the confident contact is reported normally.
        """
        uhdev = self.uhdev
        evdev = uhdev.get_evdev()

        self.confidence_change_assert_playback(uhdev, evdev, [
            # t=0: Contact 0 == Down + confident; Contact 1 == Down + confident
            # First and second finger confidently in contact
            [(self.ContactIds(contact_id = 0, tracking_id = 0, slot_num = 0), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=1: Contact 0 == Down + !confident; Contact 1 == Down + confident
            # Firtst finger looses confidence
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), True, False),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=2: Contact 0 == Down + confident; Contact 1 == Down + confident
            # First finger gains confidence
            [(self.ContactIds(contact_id = 0, tracking_id = 2, slot_num = 0), True, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)],

            # t=3: Contact 0 == !Down + confident; Contact 1 == Down + confident
            # First finger goes up
            [(self.ContactIds(contact_id = 0, tracking_id = -1, slot_num = 0), False, True),
             (self.ContactIds(contact_id = 1, tracking_id = 1, slot_num = 1), True, True)]
        ])
