/*!
 * TypeContext - Type information management for MirBuilder
 *
 * Phase 136 follow-up: Extract type-related fields from MirBuilder
 * to improve code organization and testability.
 *
 * Consolidates:
 * - value_types: ValueId -> MirType mapping
 * - value_kinds: ValueId -> MirValueKind mapping (Phase 26-A)
 * - value_origin_newbox: ValueId -> Box class name origin tracking
 */

use crate::mir::{MirType, MirValueKind, ValueId};
use std::collections::{BTreeMap, HashMap};

/// Type information context for MIR builder
///
/// Manages all type-related mappings and origin tracking for ValueIds.
#[derive(Debug, Default)]
pub(crate) struct TypeContext {
    /// Optional per-value type annotations (MIR-level): ValueId -> MirType
    /// Phase 25.1: BTreeMap for deterministic iteration
    pub value_types: BTreeMap<ValueId, MirType>,

    /// Phase 26-A: ValueId type kind mapping (type safety enhancement)
    /// ValueId -> MirValueKind mapping
    /// - GUARD bug prevention: Distinguish Parameter vs Local for ValueId(0)
    /// - Default: Unregistered ValueIds are treated as Temporary
    pub value_kinds: HashMap<ValueId, MirValueKind>,

    /// Origin tracking for simple optimizations (e.g., object.method after new)
    /// Maps a ValueId to the class name if it was produced by NewBox of that class
    /// Phase 25.1: BTreeMap for deterministic iteration
    pub value_origin_newbox: BTreeMap<ValueId, String>,
}

#[allow(dead_code)]
impl TypeContext {
    /// Create a new empty TypeContext
    pub fn new() -> Self {
        Self::default()
    }

    /// Get the type annotation for a ValueId, if present
    pub fn get_type(&self, value_id: ValueId) -> Option<&MirType> {
        self.value_types.get(&value_id)
    }

    /// Set the type annotation for a ValueId
    pub fn set_type(&mut self, value_id: ValueId, ty: MirType) {
        self.value_types.insert(value_id, ty);
    }

    /// Get the value kind for a ValueId, defaulting to Temporary if not registered
    pub fn get_kind(&self, value_id: ValueId) -> MirValueKind {
        self.value_kinds
            .get(&value_id)
            .copied()
            .unwrap_or(MirValueKind::Temporary)
    }

    /// Set the value kind for a ValueId
    pub fn set_kind(&mut self, value_id: ValueId, kind: MirValueKind) {
        self.value_kinds.insert(value_id, kind);
    }

    /// Get the origin box class name for a ValueId, if tracked
    pub fn get_origin_box(&self, value_id: ValueId) -> Option<&str> {
        self.value_origin_newbox.get(&value_id).map(|s| s.as_str())
    }

    /// Set the origin box class name for a ValueId
    pub fn set_origin_box(&mut self, value_id: ValueId, class_name: String) {
        self.value_origin_newbox.insert(value_id, class_name);
    }

    /// Clear all origin box mappings (useful for cleanup)
    pub fn clear_origin_boxes(&mut self) {
        self.value_origin_newbox.clear();
    }
}
