from prometheus_client import Counter, Histogram, Gauge, Info
from functools import wraps
import time

# License validation metrics
license_validation_total = Counter(
    'license_validation_total',
    'Total number of license validations',
    ['result', 'license_type']
)

license_validation_errors_total = Counter(
    'license_validation_errors_total',
    'Total number of license validation errors',
    ['error_type']
)

license_validation_duration_seconds = Histogram(
    'license_validation_duration_seconds',
    'License validation duration in seconds',
    buckets=[0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0]
)

# Active licenses gauge
active_licenses_total = Gauge(
    'active_licenses_total',
    'Total number of active licenses',
    ['license_type']
)

# Heartbeat metrics
license_heartbeat_total = Counter(
    'license_heartbeat_total',
    'Total number of license heartbeats received'
)

# Activation metrics
license_activation_total = Counter(
    'license_activation_total',
    'Total number of license activations',
    ['result']
)

# Anomaly detection metrics
anomaly_detections_total = Counter(
    'anomaly_detections_total',
    'Total number of anomalies detected',
    ['anomaly_type', 'severity']
)

# Concurrent sessions gauge
concurrent_sessions_total = Gauge(
    'concurrent_sessions_total',
    'Total number of concurrent active sessions'
)

# Database connection pool metrics
db_connection_pool_size = Gauge(
    'db_connection_pool_size',
    'Database connection pool size'
)

db_connection_pool_used = Gauge(
    'db_connection_pool_used',
    'Database connections currently in use'
)

# API client metrics
api_requests_total = Counter(
    'api_requests_total',
    'Total number of API requests',
    ['method', 'endpoint', 'status']
)

api_request_duration_seconds = Histogram(
    'api_request_duration_seconds',
    'API request duration in seconds',
    ['method', 'endpoint'],
    buckets=[0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1.0, 2.5, 5.0, 10.0]
)

# Cache metrics
cache_hits_total = Counter(
    'cache_hits_total',
    'Total number of cache hits',
    ['cache_type']
)

cache_misses_total = Counter(
    'cache_misses_total',
    'Total number of cache misses',
    ['cache_type']
)

# System info
system_info = Info(
    'license_server_info',
    'License server information'
)

def track_request_metrics(method: str, endpoint: str):
    """Decorator to track API request metrics"""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            start_time = time.time()
            status = "success"
            
            try:
                result = await func(*args, **kwargs)
                return result
            except Exception as e:
                status = "error"
                raise
            finally:
                duration = time.time() - start_time
                api_requests_total.labels(
                    method=method,
                    endpoint=endpoint,
                    status=status
                ).inc()
                api_request_duration_seconds.labels(
                    method=method,
                    endpoint=endpoint
                ).observe(duration)
        
        return wrapper
    return decorator

def track_validation_metrics():
    """Decorator to track license validation metrics"""
    def decorator(func):
        @wraps(func)
        async def wrapper(*args, **kwargs):
            start_time = time.time()
            
            try:
                result = await func(*args, **kwargs)
                
                # Extract result type from the validation result
                if result.get('valid'):
                    result_type = 'success'
                elif result.get('error') == 'expired':
                    result_type = 'expired'
                elif result.get('error') == 'invalid':
                    result_type = 'invalid'
                else:
                    result_type = 'error'
                
                license_type = result.get('license_type', 'unknown')
                license_validation_total.labels(
                    result=result_type,
                    license_type=license_type
                ).inc()
                
                return result
            except Exception as e:
                license_validation_errors_total.labels(
                    error_type=type(e).__name__
                ).inc()
                raise
            finally:
                duration = time.time() - start_time
                license_validation_duration_seconds.observe(duration)
        
        return wrapper
    return decorator

# Initialize system info
def init_metrics(version: str = "1.0.0"):
    """Initialize system metrics"""
    system_info.info({
        'version': version,
        'service': 'license-server'
    })