"""
Protection manager class
"""
import logging
from datetime import datetime, timezone
from typing import Dict, List, Optional

from freqtrade.persistence import PairLocks
from freqtrade.plugins.protections import IProtection
from freqtrade.resolvers import ProtectionResolver


logger = logging.getLogger(__name__)


class ProtectionManager():

    def __init__(self, config: dict) -> None:
        self._config = config

        self._protection_handlers: List[IProtection] = []
        for protection_handler_config in self._config.get('protections', []):
            protection_handler = ProtectionResolver.load_protection(
                protection_handler_config['method'],
                config=config,
                protection_config=protection_handler_config,
            )
            self._protection_handlers.append(protection_handler)

        if not self._protection_handlers:
            logger.info("No protection Handlers defined.")

    @property
    def name_list(self) -> List[str]:
        """
        Get list of loaded Protection Handler names
        """
        return [p.name for p in self._protection_handlers]

    def short_desc(self) -> List[Dict]:
        """
        List of short_desc for each Pairlist Handler
        """
        return [{p.name: p.short_desc()} for p in self._protection_handlers]

    def global_stop(self, now: Optional[datetime] = None) -> bool:
        if not now:
            now = datetime.now(timezone.utc)
        result = False
        for protection_handler in self._protection_handlers:
            if protection_handler.has_global_stop:
                result, until, reason = protection_handler.global_stop(now)

                # Early stopping - first positive result blocks further trades
                if result and until:
                    if not PairLocks.is_global_lock(until):
                        PairLocks.lock_pair('*', until, reason, now=now)
                    result = True
        return result

    def stop_per_pair(self, pair, now: Optional[datetime] = None) -> bool:
        if not now:
            now = datetime.now(timezone.utc)
        result = False
        for protection_handler in self._protection_handlers:
            if protection_handler.has_local_stop:
                result, until, reason = protection_handler.stop_per_pair(pair, now)
                if result and until:
                    if not PairLocks.is_pair_locked(pair, until):
                        PairLocks.lock_pair(pair, until, reason, now=now)
                    result = True
        return result