"""Runnable entrypoint: serve the affect provider as an ASGI app.

For the live negotiation smoke against a Worldtree instance. Config from env:
- RATATOSKR_HEIMDALL_KEY (required): HS256 shared key for the consumer, utf-8.
- RATATOSKR_AFFECT_DB   (default "affect.db"): SQLite path; ":memory:" = ephemeral.
- RATATOSKR_CONSUMER_ID (default "ratatoskr").
- RATATOSKR_PROVIDER_HOST (default "0.0.0.0"), RATATOSKR_PROVIDER_PORT (default 8390).
"""
from __future__ import annotations

import os
from collections.abc import Mapping

from ratatoskr.provider.affect_store import build_affect_provider_app, open_affect_store
from ratatoskr.provider.opfeed import maybe_instrument_from_env


def build_app_from_env(env: Mapping[str, str] | None = None):
    """Build the affect ASGI app from environment config (testable seam)."""
    env = os.environ if env is None else env
    key = env.get("RATATOSKR_HEIMDALL_KEY")
    if not key:
        raise RuntimeError(
            "RATATOSKR_HEIMDALL_KEY is required to serve the affect provider"
        )
    store = open_affect_store(env.get("RATATOSKR_AFFECT_DB", "affect.db"))
    app = build_affect_provider_app(
        store,
        heimdall_key=key.encode(),
        consumer_id=env.get("RATATOSKR_CONSUMER_ID", "ratatoskr"),
    )
    # Issue #17 (Observe): opt-in dispatch-layer op-feed when RATATOSKR_OPFEED_PATH set.
    return maybe_instrument_from_env(app, env, plane="affect")


def main() -> None:
    import uvicorn

    uvicorn.run(
        build_app_from_env(),
        host=os.environ.get("RATATOSKR_PROVIDER_HOST", "0.0.0.0"),
        port=int(os.environ.get("RATATOSKR_PROVIDER_PORT", "8390")),
    )
