//! # openfut-adapter-fifa17
//!
//! The FIFA 17 game adapter: everything that is true of *FIFA 17 specifically*
//! and must therefore stay out of OpenFUT Core and out of the generic protocol
//! crates.
//!
//! ## Layering
//!
//! ```text
//!   openfut-protocol-blaze   generic Blaze: Fire2 framing, Heat2/TDF codec
//!            ▲
//!   openfut-adapter-fifa17   THIS: FIFA 17 command tables, response bodies,
//!            ▲               dispatch ordering, session identity
//!   OpenFUT Core             game-independent FUT domain (not yet wired)
//! ```
//!
//! A second title gets its own adapter crate and reuses the protocol layer
//! underneath. Nothing here is written to be shared with one; if something in
//! this crate turns out to be title-independent, it belongs one layer down.
//!
//! ## Modules
//!
//! * [`blaze`] — the Blaze/Fire2 RPC surface. Implemented, runtime validated.
//! * [`redirector`] — the first hop's `<serverinstanceinfo>` response.
//!   Implemented; runtime validated against the retail client.
//! * [`roster`] — the FUT roster-update response, the last gate before the hub.
//!   Implemented; not yet runtime validated.
//! * [`fut`] — FUT/RS4 (UTAS) wire → Core semantic mappings; currently the
//!   owned-player ("My Squad") search: query parse + FIFA-id→name resolution +
//!   semantic filter/pagination. Pure mapping; no Rust UTAS host yet.
//!
//! Still served only by the Python backend: LSX/Origin (`:4216`), UTAS/RS4
//! (`:8099`) and POW/EASFC (`:8094`). Roster XML (`:8081`) has an adapter here
//! but no Rust host yet.
//!
//! **Nucleus (`:42131`) is deliberately not ported.** Instrumentation across
//! every live session showed the client never dials it: the listener is bound,
//! the handler logs unconditionally on connect, the client fetches the
//! `OSDK_NUCLEUS` config that carries the URL — and makes zero requests. It is
//! dead code on the observed path, so porting it would add an untested
//! component for no parity gain. See the vault's Protocol Findings.
//!
//! ## Provenance
//!
//! Ported from `fifa17-recon/tools/blaze_responder_v3b.py`, the implementation
//! that drove a retail FIFA 17 client from Origin login to an opened FUT pack.
//! Parity is tested, not asserted: `fixtures/blaze_transactions.jsonl` records
//! real request→response(s) transactions produced by the Python dispatcher, and
//! `tests/oracle_parity.rs` replays them byte-for-byte.
//!
//! ## Not a server
//!
//! This crate answers frames. It opens no socket, terminates no TLS and owns no
//! runtime. Hosting it is a separate, later decision — the Python backend
//! remains the live runtime and nothing here is wired into it.
//!
//! ```
//! use openfut_adapter_fifa17::blaze::{Adapter, AdapterConfig, Session};
//! use openfut_protocol_blaze::fire2::{Header, MsgType};
//! use openfut_protocol_blaze::heat2::Struct;
//!
//! let adapter = Adapter::new(AdapterConfig::loopback());
//! let mut session = Session::new("session-key", 0x656E5553);
//!
//! // Util::ping
//! let request = Header::new(0x0009, 0x0002, 1, MsgType::Message);
//! let out = adapter.dispatch(&request, &Struct::new(), &mut session, 1_754_870_400);
//!
//! assert_eq!(out.len(), 1);
//! assert_eq!(out[0].header.msg_type, MsgType::Reply);
//! ```

pub mod blaze;
pub mod fut;
pub mod redirector;
pub mod roster;
pub mod tls;

pub use blaze::{Adapter, AdapterConfig, Session};
