#exonware/xwsystem/src/exonware/xwsystem/shared/contracts.py
#exonware/xwsystem/shared/contracts.py
"""
Company: eXonware.com
Author: eXonware Backend Team
Email: connect@exonware.com
Version: 0.9.0.23
Generation Date: September 10, 2025
Shared protocol interfaces (merged from the former core module).
"""

from typing import Any, Protocol, runtime_checkable

from collections.abc import Iterator
from datetime import datetime
from .defs import CloneMode, CoreMode, CorePriority, CoreState, DataType
# ============================================================================
# CORE IDENTITY INTERFACES
# ============================================================================
@runtime_checkable

class IID(Protocol):
    """
    Interface for objects that have both id and uid. Both must be present and used.
    - id: Set by user/programmer. Makes it simple for systems, people, or programmers
      to find and store what they want. The programmer has the power to set it.
    - uid: Auto-generated by the system. Back-end way of ensuring uniqueness so that
      id is never duplicated. Never the same as id.
    """
    @property

    def id(self) -> str:
        """
        User/programmer-set identifier for finding and storing. Never the same as uid.
        """
        ...
    @property

    def uid(self) -> str:
        """
        System auto-generated unique identifier (e.g. UUID). Ensures uniqueness.
        """
        ...

    def generate_id(self) -> str:
        """
        Generate a new ID.
        Returns:
            New ID string
        """
        ...

    def validate_id(self, id_value: str) -> bool:
        """
        Validate an ID format.
        Args:
            id_value: ID to validate
        Returns:
            True if valid
        """
        ...

    def is_same_id(self, other: "IID") -> bool:
        """
        Check if this object has the same ID as another.
        Args:
            other: Another IID object
        Returns:
            True if same ID
        """
        ...
# ============================================================================
# NATIVE DATA CONVERSION INTERFACES
# ============================================================================
@runtime_checkable

class IStringable(Protocol):
    """
    Interface for objects that can convert to/from string representation.
    Enforces consistent string conversion behavior across XWSystem.
    """

    def to_string(self) -> str:
        """
        Convert object to string representation.
        Returns:
            String representation of the object
        """
        ...

    def from_string(self, string: str) -> bool:
        """
        Initialize object from string representation.
        Args:
            string: String representation to parse
        Returns:
            True if parsing was successful, False otherwise
        """
        ...
@runtime_checkable

class INative(Protocol):
    """
    Interface for objects that can convert to/from native Python types.
    Enforces consistent native data conversion across XWSystem.
    """

    def to_native(self) -> Any:
        """
        Convert to native Python object.
        Returns:
            Native Python object (dict, list, str, int, float, bool, etc.)
        """
        ...

    def from_native(self, data: Any) -> "INative":
        """
        Create from native Python object.
        Args:
            data: Native Python object
        Returns:
            New instance created from native data
        """
        ...

    def is_native_compatible(self, data: Any) -> bool:
        """
        Check if data is compatible with native conversion.
        Args:
            data: Data to check
        Returns:
            True if compatible
        """
        ...

    def get_native_type(self) -> DataType:
        """
        Get the native data type.
        Returns:
            DataType enum value
        """
        ...
# ============================================================================
# CORE OBJECT INTERFACE
# ============================================================================
@runtime_checkable

class IObject(IID, INative, Protocol):
    """
    Core interface for all objects in the eXonware ecosystem.
    This is the foundational object interface that combines identity (IID),
    native conversion (INative), timestamps, metadata (title/description),
    serialization, and storage operations. This interface can be used by
    xwauth, xwstorage, xwentity, and other libraries to ensure consistency.
    Objects implementing IObject can be:
    - Identified (id, uid)
    - Converted to/from native Python types (to_native, from_native)
    - Tracked with timestamps (created_at, updated_at)
    - Described with metadata (title, description)
    - Serialized (to_dict)
    - Stored and loaded (save, load)
    """
    @property

    def created_at(self) -> datetime:
        """
        Get the creation timestamp.
        Returns:
            Creation datetime
        """
        ...
    @property

    def updated_at(self) -> datetime:
        """
        Get the last update timestamp.
        Returns:
            Last update datetime
        """
        ...
    @property

    def title(self) -> str | None:
        """
        Get the object title.
        Returns:
            Title string or None if not set
        """
        ...
    @property

    def description(self) -> str | None:
        """
        Get the object description.
        Returns:
            Description string or None if not set
        """
        ...

    def to_dict(self) -> dict[str, Any]:
        """
        Export object as dictionary.
        Should include id, uid, created_at, updated_at, title, description,
        and any object-specific data.
        Returns:
            Dictionary representation of the object
        """
        ...

    def save(self, *args, **kwargs) -> None:
        """
        Save object to storage.
        Subclasses implement object-specific storage logic. This method
        can be decorated with @XWAction to enable action-based execution,
        validation, and authorization.
        Args:
            *args: Positional arguments (implementation-specific)
            **kwargs: Keyword arguments (implementation-specific)
        """
        ...

    def load(self, *args, **kwargs) -> None:
        """
        Load object from storage.
        Subclasses implement object-specific loading logic. This method
        can be decorated with @XWAction to enable action-based execution,
        validation, and authorization.
        Args:
            *args: Positional arguments (implementation-specific)
            **kwargs: Keyword arguments (implementation-specific)
        """
        ...

    def __getitem__(self, key: str) -> Any:
        """
        Get object property using dictionary-style access.
        Supports accessing properties like:
        - obj["uid"] -> returns uid property
        - obj["title"] -> returns title property
        - obj["description"] -> returns description property
        - obj["id"] -> returns id property
        - obj["created_at"] -> returns created_at property
        - obj["updated_at"] -> returns updated_at property
        - obj["property_name"] -> returns any other attribute
        Args:
            key: Property name to access
        Returns:
            Property value
        Raises:
            KeyError: If property doesn't exist
        """
        ...
# ============================================================================
# CLONING INTERFACES
# ============================================================================
@runtime_checkable

class ICloneable(Protocol):
    """
    Interface for objects that can be cloned.
    Enforces consistent cloning behavior across XWSystem.
    """

    def clone(self, mode: CloneMode = CloneMode.DEEP) -> "ICloneable":
        """
        Create a clone of this object.
        Args:
            mode: Cloning mode
        Returns:
            Cloned object
        """
        ...

    def deep_clone(self) -> "ICloneable":
        """
        Create a deep clone.
        Returns:
            Deep cloned object
        """
        ...

    def shallow_clone(self) -> "ICloneable":
        """
        Create a shallow clone.
        Returns:
            Shallow cloned object
        """
        ...

    def reference_clone(self) -> "ICloneable":
        """
        Create a reference clone (same object, different reference).
        Returns:
            Reference cloned object
        """
        ...

    def is_cloneable(self, mode: CloneMode = CloneMode.DEEP) -> bool:
        """
        Check if object can be cloned in given mode.
        Args:
            mode: Cloning mode to check
        Returns:
            True if cloneable
        """
        ...
# ============================================================================
# COMPARISON INTERFACES
# ============================================================================
@runtime_checkable

class IComparable(Protocol):
    """
    Interface for objects that can be compared.
    Enforces consistent comparison behavior across XWSystem.
    """

    def equals(self, other: Any) -> bool:
        """
        Check if this object equals another.
        Args:
            other: Object to compare
        Returns:
            True if equal
        """
        ...

    def compare_to(self, other: Any) -> int:
        """
        Compare this object to another.
        Args:
            other: Object to compare
        Returns:
            -1 if less than, 0 if equal, 1 if greater than
        """
        ...

    def hash_code(self) -> int:
        """
        Get hash code for this object.
        Returns:
            Hash code
        """
        ...

    def is_comparable(self, other: Any) -> bool:
        """
        Check if this object can be compared to another.
        Args:
            other: Object to check
        Returns:
            True if comparable
        """
        ...
# ============================================================================
# ITERATION INTERFACES
# ============================================================================
@runtime_checkable

class IIterable(Protocol):
    """
    Interface for objects that can be iterated.
    Enforces consistent iteration behavior across XWSystem.
    """

    def __iter__(self) -> Iterator[Any]:
        """
        Get iterator for this object.
        Returns:
            Iterator
        """
        ...

    def __len__(self) -> int:
        """
        Get length of this object.
        Returns:
            Length
        """
        ...

    def __contains__(self, item: Any) -> bool:
        """
        Check if object contains item.
        Args:
            item: Item to check
        Returns:
            True if contains
        """
        ...

    def is_iterable(self) -> bool:
        """
        Check if object is iterable.
        Returns:
            True if iterable
        """
        ...

    def get_iterator_type(self) -> str:
        """
        Get the type of iterator this object provides.
        Returns:
            Iterator type name
        """
        ...
# ============================================================================
# CONTAINER INTERFACES
# ============================================================================
@runtime_checkable

class IContainer(Protocol):
    """
    Interface for objects that act as containers.
    Enforces consistent container behavior across XWSystem.
    """

    def add(self, item: Any) -> bool:
        """
        Add item to container.
        Args:
            item: Item to add
        Returns:
            True if added successfully
        """
        ...

    def remove(self, item: Any) -> bool:
        """
        Remove item from container.
        Args:
            item: Item to remove
        Returns:
            True if removed successfully
        """
        ...

    def clear(self) -> None:
        """
        Clear all items from container.
        """
        ...

    def is_empty(self) -> bool:
        """
        Check if container is empty.
        Returns:
            True if empty
        """
        ...

    def size(self) -> int:
        """
        Get size of container.
        Returns:
            Number of items
        """
        ...

    def contains(self, item: Any) -> bool:
        """
        Check if container contains item.
        Args:
            item: Item to check
        Returns:
            True if contains
        """
        ...
# ============================================================================
# METADATA INTERFACES
# ============================================================================
@runtime_checkable

class IMetadata(Protocol):
    """
    Interface for objects that have metadata.
    Enforces consistent metadata handling across XWSystem.
    """

    def get_metadata(self, key: str) -> Any:
        """
        Get metadata value by key.
        Args:
            key: Metadata key
        Returns:
            Metadata value
        """
        ...

    def set_metadata(self, key: str, value: Any) -> None:
        """
        Set metadata value by key.
        Args:
            key: Metadata key
            value: Metadata value
        """
        ...

    def has_metadata(self, key: str) -> bool:
        """
        Check if metadata key exists.
        Args:
            key: Metadata key
        Returns:
            True if exists
        """
        ...

    def remove_metadata(self, key: str) -> bool:
        """
        Remove metadata by key.
        Args:
            key: Metadata key
        Returns:
            True if removed
        """
        ...

    def get_all_metadata(self) -> dict[str, Any]:
        """
        Get all metadata.
        Returns:
            Dictionary of all metadata
        """
        ...

    def clear_metadata(self) -> None:
        """
        Clear all metadata.
        """
        ...
# ============================================================================
# LIFECYCLE INTERFACES
# ============================================================================
@runtime_checkable

class ILifecycle(Protocol):
    """
    Interface for objects with lifecycle management.
    Enforces consistent lifecycle behavior across XWSystem.
    """

    def initialize(self) -> None:
        """Initialize the object."""
        ...

    def start(self) -> None:
        """Start the object."""
        ...

    def stop(self) -> None:
        """Stop the object."""
        ...

    def shutdown(self) -> None:
        """Shutdown the object."""
        ...

    def is_initialized(self) -> bool:
        """
        Check if object is initialized.
        Returns:
            True if initialized
        """
        ...

    def is_running(self) -> bool:
        """
        Check if object is running.
        Returns:
            True if running
        """
        ...

    def get_state(self) -> str:
        """
        Get current state.
        Returns:
            Current state string
        """
        ...
# ============================================================================
# FACTORY INTERFACES
# ============================================================================
@runtime_checkable

class IFactory(Protocol):
    """
    Interface for factory objects.
    Enforces consistent factory behavior across XWSystem.
    """

    def create(self, *args, **kwargs) -> Any:
        """
        Create a new instance.
        Args:
            *args: Positional arguments
            **kwargs: Keyword arguments
        Returns:
            New instance
        """
        ...

    def create_from_config(self, config: dict[str, Any]) -> Any:
        """
        Create instance from configuration.
        Args:
            config: Configuration dictionary
        Returns:
            New instance
        """
        ...

    def get_supported_types(self) -> list[str]:
        """
        Get list of supported types.
        Returns:
            List of supported type names
        """
        ...

    def can_create(self, type_name: str) -> bool:
        """
        Check if factory can create type.
        Args:
            type_name: Type name to check
        Returns:
            True if can create
        """
        ...
# ============================================================================
# CORE INTERFACE
# ============================================================================
@runtime_checkable

class ICore(Protocol):
    """Interface for core functionality."""
    @property

    def mode(self) -> CoreMode:
        """Get core mode."""
        ...
    @property

    def state(self) -> CoreState:
        """Get core state."""
        ...

    def initialize(self) -> None:
        """Initialize core functionality."""
        ...

    def shutdown(self) -> None:
        """Shutdown core functionality."""
        ...

    def is_initialized(self) -> bool:
        """Check if core is initialized."""
        ...

    def is_shutdown(self) -> bool:
        """Check if core is shutdown."""
        ...

    def get_dependencies(self) -> list[str]:
        """Get all dependencies."""
        ...

    def check_dependencies(self) -> bool:
        """Check if all dependencies are satisfied."""
        ...
# ============================================================================
# PROVIDER INTERFACES (for xwauth/xwstorage decoupling)
# ============================================================================
# These minimal basic interfaces enable dependency inversion to avoid circular
# dependencies between xwauth and xwstorage. They are defined here in xwsystem
# (the foundation) so both libraries can import them without creating circular
# dependencies.
#
# Architecture:
# - xwsystem defines IBasicProviderAuth and IBasicProviderStorage (minimal core)
# - xwstorage extends IBasicProviderAuth to IAuthProvider (full interface)
# - xwauth extends IBasicProviderStorage to IStorageProvider (full interface)
# - xwentity uses IBasicProviderAuth and IBasicProviderStorage from xwsystem
#
# Data models (User, Token, Session, etc.) stay in their original locations:
# - xwstorage/auth/interface.py - TokenValidationResult, TokenIntrospectionResult, User
# - xwauth/storage/interface.py - User, Session, Token, AuditLog, etc.
# ============================================================================
# BASIC AUTH PROVIDER INTERFACE
# ============================================================================
@runtime_checkable

class IBasicProviderAuth(Protocol):
    """
    Basic authentication provider interface (minimal core).
    This minimal interface provides only the essential auth operations needed
    by xwstorage and xwentity. Full IAuthProvider extends this with additional
    methods (validate_token, introspect_token, etc.).
    Defined in xwsystem to serve as single source of truth for all libraries.
    Uses simple types (dict, str, list) that can be replaced at runtime by
    advanced objects in external projects.
    """

    async def check_permission(
        self,
        user_id: str,
        resource: str,
        action: str
    ) -> bool:
        """
        Check if a user has permission for a resource action.
        Args:
            user_id: User identifier
            resource: Resource identifier (e.g., "bucket:my-bucket", "entity:entity_id")
            action: Action to check (e.g., "read", "write", "delete", "admin")
        Returns:
            True if user has permission, False otherwise
        """
        ...

    async def get_user_roles(self, user_id: str) -> list[str]:
        """
        Get list of roles for a user.
        Args:
            user_id: User identifier
        Returns:
            List of role names
        """
        ...

    async def validate_token(self, token: str) -> dict[str, Any]:
        """
        Validate a token and return simple token information.
        Returns a simple dict with:
        - valid: bool - Whether token is valid
        - user_id: str | None - User ID if valid
        - scopes: list[str] - List of scopes
        - expires_at: float | None - Expiration timestamp
        Args:
            token: Token string to validate
        Returns:
            Dictionary with token validation result (simple types only)
        """
        ...
# ============================================================================
# BASIC STORAGE PROVIDER INTERFACE
# ============================================================================
@runtime_checkable

class IBasicProviderStorage(Protocol):
    """
    Basic storage provider interface (minimal, generic core).
    This minimal interface provides generic CRUD operations that work with
    ANY entity/table/object type. Full IStorageProvider extends this with
    domain-specific convenience methods (save_user, get_session, etc.).
    Defined in xwsystem to serve as single source of truth for all libraries.
    The interface is entity-agnostic - it works with any entity type.
    """

    async def save(
        self,
        entity_type: str,
        entity_id: str,
        data: dict[str, Any]
    ) -> None:
        """
        Save entity to storage.
        Args:
            entity_type: Entity type identifier (e.g., "user", "session", "token", "product")
            entity_id: Entity identifier
            data: Entity data dictionary
        """
        ...

    async def get(
        self,
        entity_type: str,
        entity_id: str
    ) -> dict[str, Any] | None:
        """
        Get entity by ID.
        Args:
            entity_type: Entity type identifier
            entity_id: Entity identifier
        Returns:
            Entity data dictionary if found, None otherwise
        """
        ...

    async def get_by_field(
        self,
        entity_type: str,
        field: str,
        value: Any
    ) -> dict[str, Any] | None:
        """
        Get entity by field value.
        Args:
            entity_type: Entity type identifier
            field: Field name to search by
            value: Field value to match
        Returns:
            Entity data dictionary if found, None otherwise
        """
        ...

    async def update(
        self,
        entity_type: str,
        entity_id: str,
        updates: dict[str, Any]
    ) -> None:
        """
        Update entity data.
        Args:
            entity_type: Entity type identifier
            entity_id: Entity identifier
            updates: Dictionary of fields to update
        """
        ...

    async def delete(
        self,
        entity_type: str,
        entity_id: str
    ) -> None:
        """
        Delete entity from storage.
        Args:
            entity_type: Entity type identifier
            entity_id: Entity identifier
        """
        ...

    async def list(
        self,
        entity_type: str,
        filters: dict[str, Any] | None = None
    ) -> list[dict[str, Any]]:
        """
        List entities with optional filters.
        Args:
            entity_type: Entity type identifier
            filters: Optional filter dictionary (e.g., {"status": "active"})
        Returns:
            List of entity data dictionaries
        """
        ...
