#!/usr/bin/env python3
"""
Test script for OpenTelemetry Collector health check endpoint.

This script tests the health check endpoint on port 13133 to verify:
- Endpoint is accessible
- Returns 200 OK status
- Response contains expected JSON fields (status, uptime)
- Health check responds within acceptable time (<50ms)

Usage:
    python test-health-check.py [--endpoint http://localhost:13133]
"""

import argparse
import json
import sys
import time
from typing import Dict, Any
import urllib.request
import urllib.error


def test_health_check(endpoint: str) -> Dict[str, Any]:
    """
    Test the health check endpoint and return results.

    Args:
        endpoint: Health check endpoint URL (e.g., http://localhost:13133/)

    Returns:
        Dictionary with test results including:
        - success: bool
        - status_code: int
        - response_time_ms: float
        - response_body: dict or None
        - error: str or None
    """
    result = {
        "success": False,
        "status_code": None,
        "response_time_ms": None,
        "response_body": None,
        "error": None,
    }

    try:
        # Measure response time
        start_time = time.time()

        # Send GET request to health check endpoint
        req = urllib.request.Request(endpoint, method="GET")
        with urllib.request.urlopen(req, timeout=5) as response:
            response_time = (time.time() - start_time) * 1000  # Convert to ms
            result["response_time_ms"] = round(response_time, 2)
            result["status_code"] = response.status

            # Parse JSON response
            response_data = response.read().decode("utf-8")
            result["response_body"] = json.loads(response_data)

            # Check if status code is 200 OK
            if response.status == 200:
                result["success"] = True
            else:
                result["error"] = f"Unexpected status code: {response.status}"

    except urllib.error.HTTPError as e:
        result["status_code"] = e.code
        result["error"] = f"HTTP Error {e.code}: {e.reason}"
    except urllib.error.URLError as e:
        result["error"] = f"Connection Error: {e.reason}"
    except json.JSONDecodeError as e:
        result["error"] = f"Invalid JSON response: {e}"
    except Exception as e:
        result["error"] = f"Unexpected error: {e}"

    return result


def validate_response(response_body: Dict[str, Any]) -> Dict[str, Any]:
    """
    Validate the health check response structure.

    Args:
        response_body: Parsed JSON response from health check

    Returns:
        Dictionary with validation results:
        - valid: bool
        - missing_fields: list
        - warnings: list
    """
    validation = {"valid": True, "missing_fields": [], "warnings": []}

    # Required fields
    required_fields = ["status"]

    # Optional but expected fields
    optional_fields = ["uptime", "version", "pipelines"]

    # Check required fields
    for field in required_fields:
        if field not in response_body:
            validation["valid"] = False
            validation["missing_fields"].append(field)

    # Check optional fields
    for field in optional_fields:
        if field not in response_body:
            validation["warnings"].append(f"Optional field '{field}' not present")

    # Validate status field values
    if "status" in response_body:
        valid_statuses = ["Server available", "Server unavailable", "Degraded"]
        if response_body["status"] not in valid_statuses:
            validation["warnings"].append(f"Unexpected status value: {response_body['status']}")

    return validation


def print_results(result: Dict[str, Any], verbose: bool = False):
    """
    Print test results in a human-readable format.

    Args:
        result: Test result dictionary from test_health_check()
        verbose: If True, print detailed information
    """
    print("\n" + "=" * 60)
    print("OpenTelemetry Collector Health Check Test Results")
    print("=" * 60)

    if result["success"]:
        print("✓ Health check PASSED")
        print(f"  Status Code: {result['status_code']}")
        print(f"  Response Time: {result['response_time_ms']}ms")

        # Validate response time
        if result["response_time_ms"] > 50:
            print("  ⚠ WARNING: Response time exceeds 50ms threshold")

        # Validate response structure
        if result["response_body"]:
            validation = validate_response(result["response_body"])

            if validation["valid"]:
                print("✓ Response structure is valid")
            else:
                print("✗ Response structure validation failed")
                for field in validation["missing_fields"]:
                    print(f"  - Missing required field: {field}")

            # Print warnings
            for warning in validation["warnings"]:
                print(f"  ⚠ {warning}")

            # Print response body
            if verbose:
                print("\nResponse Body:")
                print(json.dumps(result["response_body"], indent=2))
            else:
                print(f"\nStatus: {result['response_body'].get('status', 'N/A')}")
                if "uptime" in result["response_body"]:
                    uptime = result["response_body"]["uptime"]
                    print(f"Uptime: {uptime}s ({uptime // 60}m {uptime % 60}s)")
    else:
        print("✗ Health check FAILED")
        print(f"  Error: {result['error']}")
        if result["status_code"]:
            print(f"  Status Code: {result['status_code']}")

    print("=" * 60 + "\n")


def main():
    """Main entry point for the test script."""
    parser = argparse.ArgumentParser(
        description="Test OpenTelemetry Collector health check endpoint"
    )
    parser.add_argument(
        "--endpoint",
        default="http://localhost:13133/",
        help="Health check endpoint URL (default: http://localhost:13133/)",
    )
    parser.add_argument(
        "-v", "--verbose", action="store_true", help="Print detailed response information"
    )
    parser.add_argument("--json", action="store_true", help="Output results in JSON format")

    args = parser.parse_args()

    # Run health check test
    result = test_health_check(args.endpoint)

    # Output results
    if args.json:
        print(json.dumps(result, indent=2))
    else:
        print_results(result, verbose=args.verbose)

    # Exit with appropriate code
    sys.exit(0 if result["success"] else 1)


if __name__ == "__main__":
    main()
