#!/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 = base.KernelModule("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, 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, evdev, data, t=0):
        """
        Assert properties of a list of contacts generated by make_contacts.
        """
        for contact_ids in data:
            self.assert_contact(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(
            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(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,
                    ),
                ],
            ],
        )
