# -*- coding: utf-8 -*-
# Copyright (c) 2025 ContextForge Contributors.
# SPDX-License-Identifier: Apache-2.0

"""Location: ./tests/playwright/operations/test_observability.py
Copyright 2026
SPDX-License-Identifier: Apache-2.0
Authors: Mihai Criveti

Observability & Metrics E2E Tests.

Tests health endpoints, metrics, and observability endpoints.
Observability endpoints may be disabled in test env (gracefully skipped).
"""

# Future
from __future__ import annotations

# Standard
import logging

# Third-Party
from playwright.sync_api import APIRequestContext
import pytest

logger = logging.getLogger(__name__)


def _observability_available(admin_api: APIRequestContext) -> bool:
    """Check if observability endpoints are enabled."""
    resp = admin_api.get("/observability/stats?hours=1")
    return resp.status != 404


class TestHealthEndpoints:
    """Test public health and readiness endpoints."""

    def test_health_check(self, admin_api: APIRequestContext):
        """Health endpoint returns status."""
        resp = admin_api.get("/health")
        assert resp.status == 200
        data = resp.json()
        assert data["status"] in ("healthy", "unhealthy")

    def test_readiness_check(self, admin_api: APIRequestContext):
        """Readiness endpoint returns status."""
        resp = admin_api.get("/ready")
        assert resp.status == 200
        data = resp.json()
        assert data["status"] in ("ready", "not ready")

    def test_security_health(self, admin_api: APIRequestContext):
        """Security health endpoint returns score and checks."""
        resp = admin_api.get("/health/security")
        assert resp.status == 200
        data = resp.json()
        assert "status" in data
        assert "score" in data or "checks" in data


class TestMetrics:
    """Test metrics endpoints."""

    def test_get_metrics(self, admin_api: APIRequestContext):
        """Admin can retrieve aggregated metrics."""
        resp = admin_api.get("/metrics")
        assert resp.status == 200
        data = resp.json()
        assert isinstance(data, dict)

    def test_non_admin_cannot_get_metrics(self, non_admin_api: APIRequestContext):
        """Non-admin user is denied metrics access."""
        resp = non_admin_api.get("/metrics")
        assert resp.status in (401, 403), f"Non-admin metrics should be denied, got {resp.status}"


class TestObservability:
    """Test observability endpoints (may be disabled)."""

    @pytest.fixture(autouse=True)
    def _skip_if_unavailable(self, admin_api: APIRequestContext):
        if not _observability_available(admin_api):
            pytest.skip("Observability not enabled in test environment")

    def test_get_stats(self, admin_api: APIRequestContext):
        """Admin can retrieve observability stats."""
        resp = admin_api.get("/observability/stats?hours=1")
        assert resp.status == 200
        data = resp.json()
        assert "total_traces" in data or isinstance(data, dict)

    def test_list_traces(self, admin_api: APIRequestContext):
        """Admin can list traces."""
        resp = admin_api.get("/observability/traces?limit=5")
        assert resp.status == 200

    def test_query_performance(self, admin_api: APIRequestContext):
        """Admin can query performance analytics."""
        resp = admin_api.get("/observability/analytics/query-performance?hours=1")
        assert resp.status == 200
