#!/usr/bin/env python3
"""
Configuration settings for the Text-to-GraphQL MCP Server.
This module loads environment variables from .env file and provides typed settings
classes that can be used throughout the application.
"""

import os
import json
from typing import Optional, Dict, Any
from pydantic_settings import BaseSettings
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

class Settings(BaseSettings):
    """
    Application settings loaded from environment variables
    """
    # API Keys
    OPENAI_API_KEY: str = os.getenv("OPENAI_API_KEY", "")
    
    # Model Settings
    MODEL_NAME: str = os.getenv("MODEL_NAME", "gpt-4o")
    MODEL_TEMPERATURE: float = float(os.getenv("MODEL_TEMPERATURE", "0"))
    
    # API Settings
    API_HOST: str = os.getenv("API_HOST", "127.0.0.1")
    API_PORT: int = int(os.getenv("API_PORT", "8000"))
    
    # GraphQL Settings
    GRAPHQL_ENDPOINT: str = os.getenv("GRAPHQL_ENDPOINT", "")
    GRAPHQL_API_KEY: str = os.getenv("GRAPHQL_API_KEY", "")
    GRAPHQL_HEADERS: str = os.getenv("GRAPHQL_HEADERS", "{}")
    GRAPHQL_AUTH_TYPE: str = os.getenv("GRAPHQL_AUTH_TYPE", "bearer")  # bearer, apikey, or custom
    
    # Legacy support for Arize (backward compatibility)
    ARIZE_DEVELOPER_API_KEY: str = os.getenv("ARIZE_DEVELOPER_API_KEY", "")
    
    # Optional monitoring settings (Arize Phoenix, etc.)
    ARIZE_API_KEY: str = os.getenv("ARIZE_API_KEY", "")  # For monitoring/observability
    ARIZE_PROJECT_NAME: str = os.getenv("ARIZE_PROJECT_NAME", "text-to-graphql-mcp")
    SPACE_ID: str = os.getenv("SPACE_ID", "")
    
    # LangGraph Settings
    RECURSION_LIMIT: int = int(os.getenv("RECURSION_LIMIT", "10"))
    AGENT_VERSION: str = os.getenv("AGENT_VERSION", "1.0.0")
    
    def get_graphql_headers(self) -> Dict[str, Any]:
        """
        Parse and return GraphQL headers as a dictionary.
        Supports multiple authentication methods and custom headers.
        """
        headers = {}
        
        # Parse GRAPHQL_HEADERS if provided (highest priority)
        if self.GRAPHQL_HEADERS and self.GRAPHQL_HEADERS != "{}":
            try:
                headers = json.loads(self.GRAPHQL_HEADERS)
            except json.JSONDecodeError:
                # If not valid JSON, assume it's a simple Authorization header
                headers = {"Authorization": self.GRAPHQL_HEADERS}
        
        # Auto-configure authentication if no existing auth headers and API key is provided
        api_key = self.GRAPHQL_API_KEY or self.ARIZE_DEVELOPER_API_KEY  # Support legacy
        
        if api_key and "Authorization" not in headers and "X-API-Key" not in headers:
            # Auto-detect Arize endpoint and use appropriate auth (before general auth)
            if self.GRAPHQL_ENDPOINT and "arize.com" in self.GRAPHQL_ENDPOINT:
                # Arize specifically requires X-API-Key
                headers["X-API-Key"] = api_key
            else:
                # Use configured auth type for other APIs
                auth_type = self.GRAPHQL_AUTH_TYPE.lower()
                
                if auth_type == "bearer":
                    # Standard Bearer token (most common)
                    headers["Authorization"] = f"Bearer {api_key}"
                elif auth_type == "apikey":
                    # X-API-Key header (used by some APIs like Arize)
                    headers["X-API-Key"] = api_key
                elif auth_type == "direct":
                    # Direct authorization header
                    headers["Authorization"] = api_key
                else:
                    # Default to Bearer for unknown types
                    headers["Authorization"] = f"Bearer {api_key}"
        
        # Ensure Content-Type is set
        if "Content-Type" not in headers:
            headers["Content-Type"] = "application/json"
            
        return headers
    
    class Config:
        env_file = ".env"
        extra = "ignore"

# Create a global settings instance
settings = Settings()

# Function to get settings for tests with potential overrides
def get_settings() -> Settings:
    """
    Returns application settings, allowing for potential overrides in tests
    """
    return settings 