# services/workflows/constants.py
from datetime import timedelta
from temporalio.common import RetryPolicy
# guardianhub/workflows/constants.py
from guardianhub.config.settings import settings
from guardianhub import get_logger
logger = get_logger(__name__)

# Rapid response for DB lookups
SHORT_ACTIVITY_OPTIONS = {
    "start_to_close_timeout": timedelta(seconds=60),
    "retry_policy": RetryPolicy(
        initial_interval=timedelta(seconds=1),
        backoff_coefficient=2.0,
        maximum_attempts=5,  # Higher retries for transient DB flickers
    )
}

# Standard LLM reasoning and bundle assembly
MEDIUM_ACTIVITY_OPTIONS = {
    "start_to_close_timeout": timedelta(minutes=5),
    "retry_policy": RetryPolicy(
        initial_interval=timedelta(seconds=5),
        backoff_coefficient=2.0,
        maximum_attempts=3,
    )
}

# Heavy lifting: Agentic ReAct loops and complex audits
LONG_ACTIVITY_OPTIONS = {
    "start_to_close_timeout": timedelta(minutes=30),
    "heartbeat_timeout": timedelta(minutes=1),
    "retry_policy": RetryPolicy(
        initial_interval=timedelta(seconds=10),
        maximum_attempts=2,  # Fail fast if a 30-min audit hangs twice
    )
}

def get_activity_options(activity_name: str) -> dict:
    """Assigns timeouts based on the JSON configuration."""
    wf_config = settings.workflow_settings

    if activity_name in wf_config.short_activities:
        return SHORT_ACTIVITY_OPTIONS
    if activity_name in wf_config.medium_activities:
        return MEDIUM_ACTIVITY_OPTIONS
    if activity_name in wf_config.long_activities:
        return LONG_ACTIVITY_OPTIONS

    return SHORT_ACTIVITY_OPTIONS


# guardianhub/workflows/constants.py

def get_all_activities(activity_service_instance) -> list:
    """
    Discovery Hook: Maps internal SDK roles to Specialist implementations.
    Logs role_key, method_name, and the raw_func object for deep debugging.
    """
    activities = []
    mapping = settings.workflow_settings.activity_mapping
    cls = type(activity_service_instance)
    service_name = settings.service.name

    logger.info(f"🧬 [GET_ALL_ACTIVITIES] Auditing Class: {cls.__name__}")

    for role_key, method_name in mapping.items():
        # 1. Fetch the raw function from the Class Blueprint
        raw_func = getattr(cls, method_name, None)

        # Log the discovery attempt
        logger.info(f"🕵️ [DISCOVERY] Role: '{role_key}' | Target Method: '{method_name}' | Object: {raw_func}")

        if raw_func:
            # 2. Check for the Temporal Blessing (_defn)
            has_defn = hasattr(raw_func, "_defn")

            if has_defn:
                # 3. Success: Bind it to the instance so 'self' works at runtime
                bound_method = getattr(activity_service_instance, method_name)
                activities.append(bound_method)
                logger.info(f"✅ [MATCH] Role: '{role_key}' correctly fused to {cls.__name__}.{method_name}")
            else:
                logger.warning(
                    f"❌ [MISSING_DEFN] Role: '{role_key}' found method '{method_name}', but NO @activity.defn metadata on {raw_func}")
                import warnings
                warnings.warn(f"⚠️ {service_name} missed @activity.defn on: {method_name}")
        else:
            logger.error(
                f"🚫 [NOT_FOUND] Role: '{role_key}' expects method '{method_name}' which is missing in {cls.__name__}")
            import warnings
            warnings.warn(f"⚠️ {service_name} missed implementation: {method_name}")

    logger.info(f"📊 [SUMMARY] Discovery finished. Mapped {len(activities)}/{len(mapping)} activities.")
    return activities