"""
GATT data models.
"""

from enum import Enum
from typing import Optional

from pydantic import BaseModel, Field


class CharacteristicProperty(str, Enum):
    """BLE characteristic properties."""

    BROADCAST = "broadcast"
    READ = "read"
    WRITE_WITHOUT_RESPONSE = "write-without-response"
    WRITE = "write"
    NOTIFY = "notify"
    INDICATE = "indicate"
    AUTHENTICATED_SIGNED_WRITES = "authenticated-signed-writes"
    EXTENDED_PROPERTIES = "extended-properties"


class ServiceInfo(BaseModel):
    """Information about a GATT service."""

    uuid: str = Field(..., description="Service UUID")
    handle: int = Field(..., description="Service handle")
    description: Optional[str] = Field(None, description="Service description")
    primary: bool = Field(default=True, description="Whether this is a primary service")

    model_config = {"populate_by_name": True}


class CharacteristicInfo(BaseModel):
    """Information about a GATT characteristic."""

    uuid: str = Field(..., description="Characteristic UUID")
    handle: int = Field(..., description="Characteristic handle")
    service_uuid: str = Field(..., description="Parent service UUID")
    service_description: Optional[str] = Field(None, description="Parent service description")
    properties: list[CharacteristicProperty] = Field(
        default_factory=list, description="Characteristic properties"
    )
    description: Optional[str] = Field(None, description="Characteristic description")
    max_write_without_response_size: int = Field(
        default=20, description="Maximum write size without response"
    )

    model_config = {"populate_by_name": True}


class DescriptorInfo(BaseModel):
    """Information about a GATT descriptor."""

    uuid: str = Field(..., description="Descriptor UUID")
    handle: int = Field(..., description="Descriptor handle")
    characteristic_uuid: str = Field(..., description="Parent characteristic UUID")
    description: Optional[str] = Field(None, description="Descriptor description")

    model_config = {"populate_by_name": True}
