"""Tests for Prometheus metrics definitions and instrumentation."""
from prometheus_client import Counter, Gauge, Histogram, Info

from services.shared.metrics import (
    ACTIVE_JOBS,
    AGGREGATION_CONTRADICTION_SCORE,
    AGGREGATION_DURATION,
    AGGREGATION_SIGNALS_PROCESSED,
    AGGREGATION_WINDOWS_COMPUTED,
    ALERT_ACTIVE,
    ALERT_CHECK_DURATION,
    ALERTS_FIRED,
    ALERTS_RESOLVED,
    EXTRACTION_ATTEMPTS,
    EXTRACTION_CONFIDENCE,
    EXTRACTION_DURATION,
    EXTRACTION_JOBS_TOTAL,
    EXTRACTION_RETRIES,
    EXTRACTION_TOKEN_ESTIMATE,
    EXTRACTION_VALIDATION_ERRORS,
    INGESTION_ADAPTER_DURATION,
    INGESTION_ERRORS,
    INGESTION_ITEMS_DEDUPED,
    INGESTION_ITEMS_FETCHED,
    INGESTION_ITEMS_NEW,
    INGESTION_JOBS_TOTAL,
    LAKE_FACTS_PUBLISHED,
    LAKE_PUBLISH_BYTES,
    LAKE_PUBLISH_DURATION,
    LAKE_PUBLISH_ERRORS,
    ORDERS_DUPLICATES_PREVENTED,
    ORDERS_FILLED,
    ORDERS_REJECTED,
    ORDERS_SUBMITTED,
    PARSE_DURATION,
    PARSE_JOBS_TOTAL,
    PARSE_LOW_QUALITY_TOTAL,
    PARSE_QUALITY_SCORE,
    POSITIONS_SYNCED,
    RECOMMENDATION_CONFIDENCE,
    RECOMMENDATION_GENERATED,
    RECOMMENDATION_SUPPRESSED,
    RISK_CHECK_FAILURES,
    RISK_EVALUATIONS_TOTAL,
    SERVICE_INFO,
)


def test_ingestion_metrics_are_correct_types():
    assert isinstance(INGESTION_JOBS_TOTAL, Counter)
    assert isinstance(INGESTION_ITEMS_FETCHED, Counter)
    assert isinstance(INGESTION_ITEMS_NEW, Counter)
    assert isinstance(INGESTION_ITEMS_DEDUPED, Counter)
    assert isinstance(INGESTION_ERRORS, Counter)
    assert isinstance(INGESTION_ADAPTER_DURATION, Histogram)


def test_parse_metrics_are_correct_types():
    assert isinstance(PARSE_JOBS_TOTAL, Counter)
    assert isinstance(PARSE_QUALITY_SCORE, Histogram)
    assert isinstance(PARSE_LOW_QUALITY_TOTAL, Counter)
    assert isinstance(PARSE_DURATION, Histogram)


def test_extraction_metrics_are_correct_types():
    assert isinstance(EXTRACTION_JOBS_TOTAL, Counter)
    assert isinstance(EXTRACTION_ATTEMPTS, Counter)
    assert isinstance(EXTRACTION_RETRIES, Counter)
    assert isinstance(EXTRACTION_DURATION, Histogram)
    assert isinstance(EXTRACTION_CONFIDENCE, Histogram)
    assert isinstance(EXTRACTION_VALIDATION_ERRORS, Counter)
    assert isinstance(EXTRACTION_TOKEN_ESTIMATE, Counter)


def test_aggregation_metrics_are_correct_types():
    assert isinstance(AGGREGATION_WINDOWS_COMPUTED, Counter)
    assert isinstance(AGGREGATION_SIGNALS_PROCESSED, Counter)
    assert isinstance(AGGREGATION_CONTRADICTION_SCORE, Histogram)
    assert isinstance(AGGREGATION_DURATION, Histogram)


def test_recommendation_metrics_are_correct_types():
    assert isinstance(RECOMMENDATION_GENERATED, Counter)
    assert isinstance(RECOMMENDATION_SUPPRESSED, Counter)
    assert isinstance(RECOMMENDATION_CONFIDENCE, Histogram)


def test_lake_metrics_are_correct_types():
    assert isinstance(LAKE_FACTS_PUBLISHED, Counter)
    assert isinstance(LAKE_PUBLISH_DURATION, Histogram)
    assert isinstance(LAKE_PUBLISH_ERRORS, Counter)
    assert isinstance(LAKE_PUBLISH_BYTES, Counter)


def test_trading_metrics_are_correct_types():
    assert isinstance(ORDERS_SUBMITTED, Counter)
    assert isinstance(ORDERS_REJECTED, Counter)
    assert isinstance(ORDERS_FILLED, Counter)
    assert isinstance(ORDERS_DUPLICATES_PREVENTED, Counter)
    assert isinstance(RISK_EVALUATIONS_TOTAL, Counter)
    assert isinstance(RISK_CHECK_FAILURES, Counter)
    assert isinstance(POSITIONS_SYNCED, Counter)


def test_active_jobs_gauge():
    assert isinstance(ACTIVE_JOBS, Gauge)


def test_alerting_metrics_are_correct_types():
    assert isinstance(ALERTS_FIRED, Counter)
    assert isinstance(ALERTS_RESOLVED, Counter)
    assert isinstance(ALERT_CHECK_DURATION, Histogram)
    assert isinstance(ALERT_ACTIVE, Gauge)


def test_service_info():
    assert isinstance(SERVICE_INFO, Info)


def test_counter_labels_work():
    """Verify labeled counters can be incremented without error."""
    INGESTION_JOBS_TOTAL.labels(source_type="news_api", status="success").inc()
    INGESTION_ITEMS_FETCHED.labels(source_type="market_api").inc(5)
    EXTRACTION_JOBS_TOTAL.labels(status="success").inc()
    AGGREGATION_WINDOWS_COMPUTED.labels(window="7d").inc()
    RECOMMENDATION_GENERATED.labels(action="buy", mode="paper_eligible").inc()
    LAKE_FACTS_PUBLISHED.labels(table_name="trade_signals").inc()
    ORDERS_SUBMITTED.labels(side="buy", order_type="market", mode="paper").inc()
    ORDERS_REJECTED.labels(reason_category="risk_engine").inc()
    RISK_EVALUATIONS_TOTAL.labels(result="passed").inc()


def test_histogram_observe_works():
    """Verify histograms accept observations without error."""
    INGESTION_ADAPTER_DURATION.labels(source_type="news_api").observe(1.5)
    PARSE_QUALITY_SCORE.observe(0.85)
    PARSE_DURATION.observe(0.3)
    EXTRACTION_DURATION.observe(5.2)
    EXTRACTION_CONFIDENCE.observe(0.9)
    AGGREGATION_CONTRADICTION_SCORE.observe(0.15)
    AGGREGATION_DURATION.labels(window="7d").observe(0.8)
    RECOMMENDATION_CONFIDENCE.observe(0.72)
    LAKE_PUBLISH_DURATION.labels(table_name="market_bars").observe(0.05)


def test_metrics_endpoint_import():
    """Verify the prometheus_client generate_latest works."""
    from prometheus_client import generate_latest
    output = generate_latest()
    assert isinstance(output, bytes)
    assert b"stonks_" in output
