"""RMI Backend - lifespan (startup/shutdown).

Per v4.0 §T01 + ADR-0001, lifespan wires up cross-cutting concerns:
  - Structured logging (structlog)
  - Typed error handlers (AppError → JSON)
  - Long-term memory (M1: fact_store seed)
  - Observability (M4: OpenTelemetry + Langfuse)

All initializations are isolated - one failure does not break startup.
Per v3 unfuck rule #7: add_middleware must be at module level, NOT
in lifespan. So this file only does setup() calls and yield.
"""
from __future__ import annotations

import logging
import os
from collections.abc import AsyncIterator
from contextlib import asynccontextmanager

from fastapi import FastAPI

log = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(_app: FastAPI) -> AsyncIterator[None]:
    """Wire cross-cutting at startup. Failures are logged, never fatal."""
    log.info("rmi_backend_starting")

    # 1. Structured logging
    try:
        from app.core.logging import setup_logging
        setup_logging(os.getenv("LOG_LEVEL", "INFO"))
        log.info("logging_initialized")
    except Exception as exc:
        log.warning("logging_setup_failed err=%s", exc)

    # 2. Typed error handlers
    try:
        from app.core.errors import register_error_handlers
        register_error_handlers(_app, debug=os.getenv("ENVIRONMENT") == "dev")
        log.info("error_handlers_initialized")
    except Exception as exc:
        log.warning("error_handlers_skipped err=%s", exc)

    # 3. M1 - long-term memory (fact_store seed)
    try:
        from app.agents.fact_store import seed_facts
        seeded = await seed_facts()
        log.info("fact_store_seeded count=%d", seeded)
    except Exception as exc:
        log.info("fact_store_seed_skipped err=%s", exc)

    # 4. M4 - OpenTelemetry tracing
    try:
        from app.core.tracing import setup_otel
        otel_ok = setup_otel()
        log.info("otel_init ok=%s", otel_ok)
    except Exception as exc:
        log.info("otel_init_failed err=%s", exc)

    # 5. M4 - Langfuse (LLM tracing)
    try:
        from app.core.langfuse import init_langfuse
        lf_ok = init_langfuse()
        log.info("langfuse_init ok=%s", lf_ok)
    except Exception as exc:
        log.info("langfuse_init_failed err=%s", exc)

    # 6. T07 - GlitchTip error tracking
    try:
        from app.core.observability import setup_sentry
        sentry_ok = setup_sentry()
        log.info("sentry_init ok=%s", sentry_ok)
    except Exception as exc:
        log.info("sentry_init_failed err=%s", exc)

    # 7. T12 - CertStream phishing domain monitor (background task)
    certstream_task = None
    try:
        from app.domains.threat.certstream_listener import start_listener
        certstream_task = await start_listener()
        log.info("certstream_started has_task=%s", certstream_task is not None)
    except Exception as exc:
        log.info("certstream_start_failed err=%s", exc)

    yield

    # Shutdown
    try:
        from app.domains.threat.certstream_listener import stop_listener
        await stop_listener(certstream_task)
    except Exception:
        pass
    try:
        from app.core.langfuse import flush_langfuse
        from app.core.observability import flush_sentry
        from app.core.tracing import shutdown_otel
        flush_sentry(timeout=2.0)
        flush_langfuse()
        shutdown_otel()
    except Exception:
        pass
    log.info("rmi_backend_shutdown")
