"""Class to track subscription event statistics."""
from __future__ import annotations

import logging

from soco.data_structures_entry import from_didl_string
from soco.events_base import Event as SonosEvent, parse_event_xml

_LOGGER = logging.getLogger(__name__)


class SonosStatistics:
    """Base class of Sonos statistics."""

    def __init__(self, zone_name: str, kind: str) -> None:
        """Initialize SonosStatistics."""
        self._stats = {}
        self._stat_type = kind
        self.zone_name = zone_name

    def report(self) -> dict:
        """Generate a report for use in diagnostics."""
        return self._stats.copy()

    def log_report(self) -> None:
        """Log statistics for this speaker."""
        _LOGGER.debug(
            "%s statistics for %s: %s",
            self._stat_type,
            self.zone_name,
            self.report(),
        )


class ActivityStatistics(SonosStatistics):
    """Representation of Sonos activity statistics."""

    def __init__(self, zone_name: str) -> None:
        """Initialize ActivityStatistics."""
        super().__init__(zone_name, "Activity")

    def activity(self, source: str, timestamp: float) -> None:
        """Track an activity occurrence."""
        activity_entry = self._stats.setdefault(source, {"count": 0})
        activity_entry["count"] += 1
        activity_entry["last_seen"] = timestamp


class EventStatistics(SonosStatistics):
    """Representation of Sonos event statistics."""

    def __init__(self, zone_name: str) -> None:
        """Initialize EventStatistics."""
        super().__init__(zone_name, "Event")

    def receive(self, event: SonosEvent) -> None:
        """Mark a received event by subscription type."""
        stats_entry = self._stats.setdefault(
            event.service.service_type, {"received": 0, "duplicates": 0, "processed": 0}
        )
        stats_entry["received"] += 1

    def duplicate(self, event: SonosEvent) -> None:
        """Mark a duplicate event by subscription type."""
        self._stats[event.service.service_type]["duplicates"] += 1

    def process(self, event: SonosEvent) -> None:
        """Mark a fully processed event by subscription type."""
        self._stats[event.service.service_type]["processed"] += 1

    def report(self) -> dict:
        """Generate a report for use in diagnostics."""
        payload = self._stats.copy()
        payload["soco:from_didl_string"] = from_didl_string.cache_info()
        payload["soco:parse_event_xml"] = parse_event_xml.cache_info()
        return payload
