"""
Base classes for Sideline plugins.

Provides Plugin base class and PluginMetadata for plugin registration.
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import ClassVar, Set


@dataclass
class PluginMetadata:
    """Plugin metadata with security and compatibility information."""

    name: str
    version: str
    author: str
    description: str
    sideline_version: str  # Compatible Sideline version (semver constraint)
    permissions: Set[str] = field(default_factory=set)  # Required security permissions
    capabilities: Set[str] = field(default_factory=set)  # Provided capabilities

    def validate(self) -> None:
        """Validate metadata fields."""
        if not self.name:
            raise ValueError("Plugin name cannot be empty")
        if not self.version:
            raise ValueError("Plugin version cannot be empty")
        if not self.author:
            raise ValueError("Plugin author cannot be empty")
        if not self.sideline_version:
            raise ValueError("Plugin sideline_version cannot be empty")


class StagePlugin(ABC):
    """Base class for Sideline stage plugins (distributable pipeline components).

    A StagePlugin represents a distributable unit that can contain one or more
    pipeline stages. Plugins provide metadata for security, compatibility,
    and versioning.

    Subclasses must implement:
    - validate_security(granted_permissions) -> bool
    """

    metadata: ClassVar[PluginMetadata]

    @abstractmethod
    def validate_security(self, granted_permissions: Set[str]) -> bool:
        """Check if plugin has required permissions.

        Args:
            granted_permissions: Set of granted security permissions

        Returns:
            True if plugin has all required permissions
        """
        pass

    @classmethod
    def get_metadata(cls) -> PluginMetadata:
        """Get plugin metadata."""
        return cls.metadata

    @classmethod
    def get_required_permissions(cls) -> Set[str]:
        """Get required security permissions."""
        return cls.metadata.permissions

    @classmethod
    def get_provided_capabilities(cls) -> Set[str]:
        """Get provided capabilities."""
        return cls.metadata.capabilities


# Backward compatibility alias
Plugin = StagePlugin
