""" Repository interfaces for method rotation system. These interfaces define the contracts for data access without implementation details. """ from abc import ABC, abstractmethod from datetime import datetime, date from typing import List, Optional, Dict, Any from domain.entities.method_rotation import ( MethodStrategy, RotationSession, RotationEvent, PlatformMethodState ) class IMethodStrategyRepository(ABC): """Interface for method strategy data access""" @abstractmethod def save(self, strategy: MethodStrategy) -> None: """Save or update a method strategy""" pass @abstractmethod def find_by_id(self, strategy_id: str) -> Optional[MethodStrategy]: """Find a strategy by its ID""" pass @abstractmethod def find_by_platform(self, platform: str) -> List[MethodStrategy]: """Find all strategies for a platform""" pass @abstractmethod def find_active_by_platform(self, platform: str) -> List[MethodStrategy]: """Find all active strategies for a platform, ordered by effectiveness""" pass @abstractmethod def find_by_platform_and_method(self, platform: str, method_name: str) -> Optional[MethodStrategy]: """Find a specific method strategy""" pass @abstractmethod def update_performance_metrics(self, strategy_id: str, success: bool, execution_time: float = 0.0) -> None: """Update performance metrics for a strategy""" pass @abstractmethod def get_next_available_method(self, platform: str, excluded_methods: List[str] = None, max_risk_level: str = "HIGH") -> Optional[MethodStrategy]: """Get the next best available method for a platform""" pass @abstractmethod def disable_method(self, platform: str, method_name: str, reason: str) -> None: """Disable a method temporarily or permanently""" pass @abstractmethod def enable_method(self, platform: str, method_name: str) -> None: """Re-enable a disabled method""" pass @abstractmethod def get_platform_statistics(self, platform: str) -> Dict[str, Any]: """Get aggregated statistics for all methods on a platform""" pass @abstractmethod def cleanup_old_data(self, days_to_keep: int = 90) -> int: """Clean up old performance data and return number of records removed""" pass class IRotationSessionRepository(ABC): """Interface for rotation session data access""" @abstractmethod def save(self, session: RotationSession) -> None: """Save or update a rotation session""" pass @abstractmethod def find_by_id(self, session_id: str) -> Optional[RotationSession]: """Find a session by its ID""" pass @abstractmethod def find_active_session(self, platform: str, account_id: Optional[str] = None) -> Optional[RotationSession]: """Find an active session for a platform/account""" pass @abstractmethod def find_active_sessions_by_platform(self, platform: str) -> List[RotationSession]: """Find all active sessions for a platform""" pass @abstractmethod def update_session_metrics(self, session_id: str, success: bool, method_name: str, error_message: Optional[str] = None) -> None: """Update session metrics after a method attempt""" pass @abstractmethod def archive_session(self, session_id: str, final_success: bool = False) -> None: """Mark a session as completed/archived""" pass @abstractmethod def get_session_history(self, platform: str, limit: int = 100) -> List[RotationSession]: """Get recent session history for a platform""" pass @abstractmethod def get_session_statistics(self, platform: str, days: int = 30) -> Dict[str, Any]: """Get session statistics for a platform over specified days""" pass @abstractmethod def cleanup_old_sessions(self, days_to_keep: int = 30) -> int: """Clean up old session data and return number of records removed""" pass class IRotationEventRepository(ABC): """Interface for rotation event data access""" @abstractmethod def save(self, event: RotationEvent) -> None: """Save a rotation event""" pass @abstractmethod def save_batch(self, events: List[RotationEvent]) -> None: """Save multiple events in a batch for performance""" pass @abstractmethod def find_by_session(self, session_id: str) -> List[RotationEvent]: """Find all events for a specific session""" pass @abstractmethod def find_by_method(self, platform: str, method_name: str, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None) -> List[RotationEvent]: """Find events for a specific method within date range""" pass @abstractmethod def find_recent_failures(self, platform: str, method_name: str, hours: int = 24) -> List[RotationEvent]: """Find recent failure events for a method""" pass @abstractmethod def get_event_statistics(self, platform: str, start_date: Optional[datetime] = None, end_date: Optional[datetime] = None) -> Dict[str, Any]: """Get event statistics for analysis""" pass @abstractmethod def get_error_patterns(self, platform: str, method_name: str, days: int = 7) -> Dict[str, int]: """Get error patterns for a method to identify common issues""" pass @abstractmethod def cleanup_old_events(self, days_to_keep: int = 90) -> int: """Clean up old event data and return number of records removed""" pass class IPlatformMethodStateRepository(ABC): """Interface for platform method state data access""" @abstractmethod def save(self, state: PlatformMethodState) -> None: """Save or update platform method state""" pass @abstractmethod def find_by_platform(self, platform: str) -> Optional[PlatformMethodState]: """Find method state for a platform""" pass @abstractmethod def get_or_create_state(self, platform: str) -> PlatformMethodState: """Get existing state or create new one with defaults""" pass @abstractmethod def update_daily_attempts(self, platform: str, method_name: str) -> None: """Increment daily attempt counter for a method""" pass @abstractmethod def reset_daily_counters(self, platform: str) -> None: """Reset daily attempt counters (typically called at midnight)""" pass @abstractmethod def block_method(self, platform: str, method_name: str, reason: str) -> None: """Block a method temporarily""" pass @abstractmethod def unblock_method(self, platform: str, method_name: str) -> None: """Unblock a previously blocked method""" pass @abstractmethod def record_method_success(self, platform: str, method_name: str) -> None: """Record successful method execution""" pass @abstractmethod def get_preferred_method_order(self, platform: str) -> List[str]: """Get preferred method order for a platform""" pass @abstractmethod def set_emergency_mode(self, platform: str, enabled: bool) -> None: """Enable/disable emergency mode for a platform""" pass class IMethodPerformanceRepository(ABC): """Interface for method performance analytics data access""" @abstractmethod def record_daily_performance(self, platform: str, method_name: str, success: bool, execution_time: float = 0.0) -> None: """Record performance data for daily aggregation""" pass @abstractmethod def get_daily_performance(self, platform: str, method_name: str, start_date: date, end_date: date) -> List[Dict[str, Any]]: """Get daily performance data for a method within date range""" pass @abstractmethod def get_method_trends(self, platform: str, days: int = 30) -> Dict[str, Any]: """Get performance trends for all methods on a platform""" pass @abstractmethod def get_success_rate_history(self, platform: str, method_name: str, days: int = 30) -> List[Dict[str, Any]]: """Get success rate history for trend analysis""" pass @abstractmethod def get_peak_usage_patterns(self, platform: str, method_name: str) -> Dict[str, Any]: """Get usage patterns to identify peak hours and optimize timing""" pass @abstractmethod def aggregate_daily_stats(self, target_date: date) -> int: """Aggregate raw performance data into daily statistics""" pass @abstractmethod def cleanup_old_performance_data(self, days_to_keep: int = 365) -> int: """Clean up old performance data and return number of records removed""" pass class IMethodCooldownRepository(ABC): """Interface for method cooldown data access""" @abstractmethod def add_cooldown(self, platform: str, method_name: str, cooldown_until: datetime, reason: str) -> None: """Add a cooldown period for a method""" pass @abstractmethod def remove_cooldown(self, platform: str, method_name: str) -> None: """Remove cooldown for a method""" pass @abstractmethod def is_method_on_cooldown(self, platform: str, method_name: str) -> bool: """Check if a method is currently on cooldown""" pass @abstractmethod def get_cooldown_info(self, platform: str, method_name: str) -> Optional[Dict[str, Any]]: """Get cooldown information for a method""" pass @abstractmethod def get_active_cooldowns(self, platform: str) -> List[Dict[str, Any]]: """Get all active cooldowns for a platform""" pass @abstractmethod def cleanup_expired_cooldowns(self) -> int: """Remove expired cooldowns and return number of records removed""" pass @abstractmethod def extend_cooldown(self, platform: str, method_name: str, additional_seconds: int) -> None: """Extend existing cooldown period""" pass