import cherrypy
from functools import wraps
import logging

logger = logging.getLogger(__name__)


def require_auth(func):

    @wraps(func)
    def wrapper(*args, **kwargs):
        # Skip authentication for OPTIONS requests (CORS preflight)
        if cherrypy.request.method == 'OPTIONS':
            return func(*args, **kwargs)
        
        # Get auth handlers from global cherrypy config (not app config)
        jwt_handler = cherrypy.config.get('jwt_handler')
        token_manager = cherrypy.config.get('token_manager')
        
        if not jwt_handler or not token_manager:
            logger.error("Auth handlers not configured")
            raise cherrypy.HTTPError(500, "Authentication not configured")
        
        # Try JWT authentication first
        auth_header = cherrypy.request.headers.get('Authorization', '')
        if auth_header.startswith('Bearer '):
            token = auth_header[7:]  # Remove 'Bearer ' prefix
            payload = jwt_handler.verify_jwt(token)
            
            if payload:
                # JWT is valid
                cherrypy.request.user = {
                    'username': payload['sub'],
                    'client_id': payload['client_id'],
                    'auth_type': 'jwt'
                }
                return func(*args, **kwargs)
            else:
                logger.warning("Invalid or expired JWT token")
        
        # Try API token authentication
        api_key = cherrypy.request.headers.get('X-API-Key', '')
        if api_key:
            token_info = token_manager.verify_token(api_key)
            
            if token_info:
                # API token is valid
                cherrypy.request.user = {
                    'username': 'api_token',
                    'token_name': token_info['name'],
                    'token_id': token_info['id'],
                    'auth_type': 'api_token'
                }
                return func(*args, **kwargs)
            else:
                logger.warning("Invalid API token")
        
        # No valid authentication found
        logger.warning(f"Unauthorized access attempt to {cherrypy.request.path_info}")
        
        cherrypy.response.status = 401
        cherrypy.response.headers['Content-Type'] = 'application/json'
        return {'success': False, 'error': 'Unauthorized - Valid JWT or API token required'}
    
    return wrapper