"""
MCP Configuration Management Server
===================================

Provides configuration management tools for Storm Logger MCP servers
with centralized configuration, validation, and runtime updates.
"""

import asyncio
import json
import os
from typing import Dict, Any, Optional, List

from fastmcp import FastMCP
from ..config_manager import config_manager, ConfigSource

# Initialize the FastMCP server
server = FastMCP("Configuration Management Server")

@server.tool(tags={"configuration", "management"})
def get_server_config(server_name: str) -> Dict:
    """
    Get configuration for a specific MCP server.
    
    Args:
        server_name: Name of the server to get configuration for
        
    Returns:
        Dict containing server configuration and metadata
    """
    config = config_manager.get_server_config(server_name)
    
    if not config:
        return {
            "status": "error",
            "message": f"Server '{server_name}' not found in configuration",
            "available_servers": list(config_manager.config.servers.keys())
        }
    
    return {
        "status": "success",
        "server_name": server_name,
        "config": {
            "enabled": config.enabled,
            "max_connections": config.max_connections,
            "request_timeout": config.request_timeout,
            "health_check_interval": config.health_check_interval,
            "log_level": config.log_level,
            "tools_enabled": config.tools_enabled,
            "custom_settings": config.custom_settings
        },
        "config_sources": {
            key: source.value for key, source in config_manager.config_sources.items()
            if key.startswith(f"servers.{server_name}")
        }
    }

@server.tool(tags={"configuration", "management"})
def update_server_config(server_name: str, enabled: Optional[bool] = None, 
                        max_connections: Optional[int] = None, 
                        request_timeout: Optional[int] = None,
                        health_check_interval: Optional[int] = None,
                        log_level: Optional[str] = None) -> Dict:
    """
    Update configuration for a specific MCP server.
    
    Args:
        server_name: Name of the server to update
        enabled: Enable/disable the server
        max_connections: Maximum number of connections
        request_timeout: Request timeout in seconds
        health_check_interval: Health check interval in seconds
        log_level: Logging level
        
    Returns:
        Dict containing update status and new configuration
    """
    try:
        # Build kwargs from provided parameters
        kwargs = {}
        if enabled is not None:
            kwargs['enabled'] = enabled
        if max_connections is not None:
            kwargs['max_connections'] = max_connections
        if request_timeout is not None:
            kwargs['request_timeout'] = request_timeout
        if health_check_interval is not None:
            kwargs['health_check_interval'] = health_check_interval
        if log_level is not None:
            kwargs['log_level'] = log_level
        
        if not kwargs:
            return {
                "status": "error",
                "message": "No parameters provided for update",
                "server_name": server_name
            }
        
        # Update configuration
        config_manager.update_server_config(server_name, **kwargs)
        
        # Get updated configuration
        updated_config = config_manager.get_server_config(server_name)
        
        return {
            "status": "success",
            "message": f"Configuration updated for server '{server_name}'",
            "updated_config": {
                "enabled": updated_config.enabled,
                "max_connections": updated_config.max_connections,
                "request_timeout": updated_config.request_timeout,
                "health_check_interval": updated_config.health_check_interval,
                "log_level": updated_config.log_level,
                "tools_enabled": updated_config.tools_enabled,
                "custom_settings": updated_config.custom_settings
            },
            "updated_parameters": list(kwargs.keys())
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to update configuration: {str(e)}",
            "server_name": server_name
        }

@server.tool(tags={"configuration", "monitoring"})
def get_monitoring_config() -> Dict:
    """
    Get monitoring system configuration.
    
    Returns:
        Dict containing monitoring configuration
    """
    config = config_manager.get_monitoring_config()
    
    return {
        "status": "success",
        "monitoring_config": {
            "enabled": config.enabled,
            "metrics_collection_interval": config.metrics_collection_interval,
            "dashboard_enabled": config.dashboard_enabled,
            "dashboard_port": config.dashboard_port,
            "alert_thresholds": config.alert_thresholds,
            "performance_monitoring": config.performance_monitoring,
            "business_intelligence": config.business_intelligence
        },
        "config_sources": {
            key: source.value for key, source in config_manager.config_sources.items()
            if key.startswith("monitoring")
        }
    }

@server.tool(tags={"configuration", "monitoring"})
def update_monitoring_config(**kwargs) -> Dict:
    """
    Update monitoring system configuration.
    
    Args:
        **kwargs: Monitoring configuration parameters to update
        
    Returns:
        Dict containing update status
    """
    try:
        valid_params = {
            'enabled', 'metrics_collection_interval', 'dashboard_enabled',
            'dashboard_port', 'alert_thresholds', 'performance_monitoring',
            'business_intelligence'
        }
        
        invalid_params = set(kwargs.keys()) - valid_params
        if invalid_params:
            return {
                "status": "error",
                "message": f"Invalid parameters: {', '.join(invalid_params)}",
                "valid_parameters": list(valid_params)
            }
        
        config_manager.update_monitoring_config(**kwargs)
        
        return {
            "status": "success",
            "message": "Monitoring configuration updated successfully",
            "updated_parameters": list(kwargs.keys())
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to update monitoring configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "security"})
def get_security_config() -> Dict:
    """
    Get security configuration.
    
    Returns:
        Dict containing security configuration
    """
    config = config_manager.get_security_config()
    
    return {
        "status": "success",
        "security_config": {
            "authentication_enabled": config.authentication_enabled,
            "api_key_required": config.api_key_required,
            "rate_limiting_enabled": config.rate_limiting_enabled,
            "max_requests_per_minute": config.max_requests_per_minute,
            "allowed_hosts": config.allowed_hosts,
            "tls_enabled": config.tls_enabled,
            "certificate_path": config.certificate_path,
            "private_key_path": config.private_key_path
        },
        "config_sources": {
            key: source.value for key, source in config_manager.config_sources.items()
            if key.startswith("security")
        }
    }

@server.tool(tags={"configuration", "security"})
def update_security_config(**kwargs) -> Dict:
    """
    Update security configuration.
    
    Args:
        **kwargs: Security configuration parameters to update
        
    Returns:
        Dict containing update status
    """
    try:
        valid_params = {
            'authentication_enabled', 'api_key_required', 'rate_limiting_enabled',
            'max_requests_per_minute', 'allowed_hosts', 'tls_enabled',
            'certificate_path', 'private_key_path'
        }
        
        invalid_params = set(kwargs.keys()) - valid_params
        if invalid_params:
            return {
                "status": "error",
                "message": f"Invalid parameters: {', '.join(invalid_params)}",
                "valid_parameters": list(valid_params)
            }
        
        config_manager.update_security_config(**kwargs)
        
        return {
            "status": "success",
            "message": "Security configuration updated successfully",
            "updated_parameters": list(kwargs.keys())
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to update security configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "logging"})
def get_logging_config() -> Dict:
    """
    Get logging configuration.
    
    Returns:
        Dict containing logging configuration
    """
    config = config_manager.get_logging_config()
    
    return {
        "status": "success",
        "logging_config": {
            "level": config.level,
            "format": config.format,
            "file_enabled": config.file_enabled,
            "file_path": config.file_path,
            "console_enabled": config.console_enabled,
            "max_file_size": config.max_file_size,
            "backup_count": config.backup_count,
            "structured_logging": config.structured_logging
        },
        "config_sources": {
            key: source.value for key, source in config_manager.config_sources.items()
            if key.startswith("logging")
        }
    }

@server.tool(tags={"configuration", "logging"})
def update_logging_config(**kwargs) -> Dict:
    """
    Update logging configuration.
    
    Args:
        **kwargs: Logging configuration parameters to update
        
    Returns:
        Dict containing update status
    """
    try:
        valid_params = {
            'level', 'format', 'file_enabled', 'file_path', 'console_enabled',
            'max_file_size', 'backup_count', 'structured_logging'
        }
        
        invalid_params = set(kwargs.keys()) - valid_params
        if invalid_params:
            return {
                "status": "error",
                "message": f"Invalid parameters: {', '.join(invalid_params)}",
                "valid_parameters": list(valid_params)
            }
        
        config_manager.update_logging_config(**kwargs)
        
        return {
            "status": "success",
            "message": "Logging configuration updated successfully",
            "updated_parameters": list(kwargs.keys())
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to update logging configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "global"})
def get_global_settings() -> Dict:
    """
    Get global settings.
    
    Returns:
        Dict containing global settings
    """
    settings = config_manager.get_global_settings()
    
    return {
        "status": "success",
        "global_settings": settings,
        "config_sources": {
            key: source.value for key, source in config_manager.config_sources.items()
            if key.startswith("global_settings")
        }
    }

@server.tool(tags={"configuration", "global"})
def update_global_settings(**kwargs) -> Dict:
    """
    Update global settings.
    
    Args:
        **kwargs: Global settings to update
        
    Returns:
        Dict containing update status
    """
    try:
        config_manager.update_global_settings(**kwargs)
        
        return {
            "status": "success",
            "message": "Global settings updated successfully",
            "updated_settings": list(kwargs.keys())
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to update global settings: {str(e)}"
        }

@server.tool(tags={"configuration", "management"})
def get_config_summary() -> Dict:
    """
    Get complete configuration summary.
    
    Returns:
        Dict containing complete configuration summary
    """
    try:
        summary = config_manager.get_config_summary()
        
        return {
            "status": "success",
            "config_summary": summary,
            "statistics": {
                "total_servers": len(summary['servers']),
                "enabled_servers": sum(1 for s in summary['servers'].values() if s['enabled']),
                "config_sources": len(summary['config_sources']),
                "config_file": summary['config_file'],
                "last_modified": summary['last_modified']
            }
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to get configuration summary: {str(e)}"
        }

@server.tool(tags={"configuration", "import_export"})
def export_config(format: str = "json") -> Dict:
    """
    Export current configuration.
    
    Args:
        format: Export format (json, yaml)
        
    Returns:
        Dict containing exported configuration
    """
    try:
        exported_config = config_manager.export_config(format)
        
        return {
            "status": "success",
            "format": format,
            "config": exported_config,
            "size": len(exported_config),
            "message": f"Configuration exported successfully in {format} format"
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to export configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "import_export"})
def import_config(config_data: str, format: str = "json") -> Dict:
    """
    Import configuration from string.
    
    Args:
        config_data: Configuration data as string
        format: Import format (json, yaml)
        
    Returns:
        Dict containing import status
    """
    try:
        config_manager.import_config(config_data, format)
        
        return {
            "status": "success",
            "format": format,
            "message": f"Configuration imported successfully from {format} format",
            "restart_required": True
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to import configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "management"})
def reset_to_defaults() -> Dict:
    """
    Reset configuration to default values.
    
    Returns:
        Dict containing reset status
    """
    try:
        config_manager.reset_to_defaults()
        
        return {
            "status": "success",
            "message": "Configuration reset to defaults successfully",
            "restart_required": True
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to reset configuration: {str(e)}"
        }

@server.tool(tags={"configuration", "validation"})
def validate_config() -> Dict:
    """
    Validate current configuration.
    
    Returns:
        Dict containing validation results
    """
    try:
        # Trigger validation
        config_manager._validate_configuration()
        
        return {
            "status": "success",
            "message": "Configuration validation passed",
            "valid": True
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Configuration validation failed: {str(e)}",
            "valid": False
        }

@server.tool(tags={"configuration", "environment"})
def get_environment_variables() -> Dict:
    """
    Get MCP-related environment variables.
    
    Returns:
        Dict containing environment variables
    """
    env_vars = {}
    mcp_prefixes = ['MCP_', 'STORM_', 'FASTMCP_']
    
    for key, value in os.environ.items():
        if any(key.startswith(prefix) for prefix in mcp_prefixes):
            env_vars[key] = value
    
    return {
        "status": "success",
        "environment_variables": env_vars,
        "count": len(env_vars),
        "message": "Environment variables retrieved successfully"
    }

@server.tool(tags={"configuration", "templates"})
def get_config_templates() -> Dict:
    """
    Get configuration templates for different deployment scenarios.
    
    Returns:
        Dict containing configuration templates
    """
    templates = {
        "development": {
            "global_settings": {
                "debug_mode": True,
                "development_mode": True,
                "environment": "development"
            },
            "monitoring": {
                "enabled": True,
                "dashboard_enabled": True,
                "dashboard_port": 8080
            },
            "security": {
                "authentication_enabled": False,
                "rate_limiting_enabled": False
            },
            "logging": {
                "level": "DEBUG",
                "console_enabled": True,
                "file_enabled": True
            }
        },
        "production": {
            "global_settings": {
                "debug_mode": False,
                "development_mode": False,
                "environment": "production"
            },
            "monitoring": {
                "enabled": True,
                "dashboard_enabled": True,
                "dashboard_port": 8080
            },
            "security": {
                "authentication_enabled": True,
                "rate_limiting_enabled": True,
                "max_requests_per_minute": 1000
            },
            "logging": {
                "level": "INFO",
                "console_enabled": False,
                "file_enabled": True
            }
        },
        "high_security": {
            "global_settings": {
                "debug_mode": False,
                "development_mode": False,
                "environment": "production"
            },
            "monitoring": {
                "enabled": True,
                "dashboard_enabled": False
            },
            "security": {
                "authentication_enabled": True,
                "api_key_required": True,
                "rate_limiting_enabled": True,
                "max_requests_per_minute": 100,
                "tls_enabled": True
            },
            "logging": {
                "level": "WARNING",
                "console_enabled": False,
                "file_enabled": True,
                "structured_logging": True
            }
        }
    }
    
    return {
        "status": "success",
        "templates": templates,
        "available_templates": list(templates.keys()),
        "message": "Configuration templates retrieved successfully"
    }

@server.tool(tags={"configuration", "templates"})
def apply_config_template(template_name: str) -> Dict:
    """
    Apply a configuration template.
    
    Args:
        template_name: Name of the template to apply
        
    Returns:
        Dict containing application status
    """
    try:
        templates = get_config_templates()["templates"]
        
        if template_name not in templates:
            return {
                "status": "error",
                "message": f"Template '{template_name}' not found",
                "available_templates": list(templates.keys())
            }
        
        template = templates[template_name]
        
        # Apply template configuration
        if "global_settings" in template:
            config_manager.update_global_settings(**template["global_settings"])
        
        if "monitoring" in template:
            config_manager.update_monitoring_config(**template["monitoring"])
        
        if "security" in template:
            config_manager.update_security_config(**template["security"])
        
        if "logging" in template:
            config_manager.update_logging_config(**template["logging"])
        
        return {
            "status": "success",
            "template_name": template_name,
            "message": f"Template '{template_name}' applied successfully",
            "restart_required": True
        }
        
    except Exception as e:
        return {
            "status": "error",
            "message": f"Failed to apply template: {str(e)}"
        }

@server.tool(tags={"health", "internal"})
def health_check() -> Dict:
    """Health check for configuration server."""
    import time
    checks = {
        "server_operational": True,
        "tools_available": True,
        "config_manager_loaded": True,
        "config_file_accessible": True
    }
    
    try:
        # Test config manager
        config_manager.get_config_summary()
        checks["config_manager_loaded"] = True
        
        # Test config file
        if hasattr(config_manager, 'config_file'):
            checks["config_file_accessible"] = config_manager.config_file.parent.exists()
        
    except Exception as e:
        checks["config_manager_loaded"] = False
        checks["config_file_accessible"] = False
    
    return {
        "status": "healthy" if all(checks.values()) else "warning",
        "checks": checks,
        "timestamp": time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
        "server": "config"
    }

if __name__ == "__main__":
    server.run()