import requests
from typing import Dict, Any
from gudb.providers.base import BaseProvider
from gudb.config import settings
from gudb.utils.logging import get_logger
from gudb.utils.circuit_breaker import CircuitBreaker, CircuitBreakerOpenError

logger = get_logger("provider.remote")

class RemoteGudbProvider(BaseProvider):
    """
    Provider that calls a remote gudb Backend API.
    Includes circuit breaker to prevent cascade failures.
    
    SECURITY GUARANTEE:
    - Requires explicit endpoint configuration or raises ValueError
    - No hardcoded URLs, no default endpoints
    - Only used when mode="remote" or mode="hybrid" AND api_endpoint is explicitly set
    - Never instantiated in local-only mode (default)
    """
    
    def __init__(self, endpoint: str = None):
        self.endpoint = endpoint or settings.api_endpoint
        if not self.endpoint:
            raise ValueError(
                "Remote provider requires api_endpoint. "
                "Set GUDB_API_ENDPOINT environment variable or pass endpoint parameter. "
                "This prevents unintentional network calls and data exfiltration."
            )
        
        # Circuit breaker: 5 failures, 60s timeout
        self.circuit_breaker = CircuitBreaker(
            failure_threshold=5,
            timeout=60,
            expected_exception=requests.exceptions.RequestException
        )

    def evaluate(self, query: str, context: Dict[str, Any]) -> Dict[str, Any]:
        try:
            # Use circuit breaker to prevent repeated failures
            return self.circuit_breaker.call(self._call_api, query, context)
        except CircuitBreakerOpenError as e:
            logger.warning(f"Circuit breaker open: {e}")
            return {"verdict": "GO", "error": "Circuit breaker open"}
        except requests.exceptions.RequestException as e:
            logger.warning(f"Failed to reach gudb backend: {e}")
            return {"verdict": "GO", "error": "Backend unreachable"}
    
    def _call_api(self, query: str, context: Dict[str, Any]) -> Dict[str, Any]:
        """Internal method to call the remote API"""
        payload = {
            "query": query,
            "stack_trace": context.get("stack_trace"),
            "git_info": context.get("git_info"),
            "env": settings.environment
        }
        
        response = requests.post(
            self.endpoint, 
            json=payload, 
            timeout=settings.timeout_seconds
        )
        
        if response.status_code == 200:
            return response.json()
        else:
            logger.error(f"Backend returned status {response.status_code}")
            raise requests.exceptions.HTTPError(f"HTTP {response.status_code}")
