//! Perception-side helpers shared across platform backends.
//!
//! Today this is a thin module; as CD-02 through CD-06 land, the
//! common AX-walk bookkeeping and a11y-index construction moves
//! here so the platform backends stay focused on their
//! platform-specific data sources.

use std::collections::HashMap;

use chrono::Utc;

use crate::models::{A11yElementRecord, A11yNode, UiMap, WindowInfo};

/// Build a `UiMap` whose AX tree is explicitly absent. Used by
/// `observe_window` callers on targets that render without AX
/// exposure (notably Bevy-based surfaces). Callers combine this
/// with a pixel `Frame` via `UiMap { frame: Some(..), .. }` before
/// returning to the executor.
pub fn empty_a11y_uimap(window: WindowInfo) -> UiMap {
    UiMap {
        window,
        frame: None,
        a11y_root: None,
        a11y_index: Vec::new(),
        a11y_by_id: HashMap::new(),
        a11y_truncated: false,
        a11y_empty: true,
        observed_at: Utc::now(),
    }
}

/// Build a `UiMap` from an AX root node, the flattened BFS index,
/// and an id-indexed lookup map. Called by the macOS AX walker
/// (CD-04) after finishing its traversal.
pub fn populated_uimap(
    window: WindowInfo,
    root: A11yNode,
    a11y_index: Vec<String>,
    a11y_by_id: HashMap<String, A11yElementRecord>,
    truncated: bool,
) -> UiMap {
    UiMap {
        window,
        frame: None,
        a11y_root: Some(root),
        a11y_index,
        a11y_by_id,
        a11y_truncated: truncated,
        a11y_empty: false,
        observed_at: Utc::now(),
    }
}

/// Maximum AX tree depth before truncation. Matches the value
/// called out in docs/CAR_DESKTOP.md.
pub const AX_DEPTH_CAP: usize = 24;

/// Maximum total node count. Walks that hit this cap return early
/// and flag `UiMap.a11y_truncated = true`.
pub const AX_NODE_CAP: usize = 2048;
