use std::collections::HashMap;

use eidos_kernel::schema::{Edge, Node};

/// The nodes, structural edges, and reference candidates extracted from a single source file.
#[derive(Default)]
pub(crate) struct FileGraph {
    pub(crate) nodes: Vec<Node>,
    pub(crate) edges: Vec<Edge>,
    pub(crate) parse_error: bool,
    /// `(source item id, distinct identifier names in its body)` — resolved to `references` edges
    /// in a second pass (`compile_code`) once the global name index across all files exists.
    pub(crate) refs: Vec<(String, Vec<RefName>)>,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub(crate) struct RefName {
    pub(crate) name: String,
    pub(crate) imported_mod: Option<String>,
    /// For a method call whose receiver type was inferred (`self.memory.append()` → receiver
    /// `Memory`), the type name. Lets the resolver pick the ONE `Memory::append` when the bare name
    /// `append` is ambiguous across classes — turning a dropped ambiguous reference into a proven,
    /// trusted call-graph edge. `None` for ordinary identifiers.
    pub(crate) receiver_type: Option<String>,
}

impl RefName {
    pub(crate) fn lexical(name: String) -> Self {
        Self {
            name,
            imported_mod: None,
            receiver_type: None,
        }
    }

    /// A method reference whose receiver type was inferred.
    pub(crate) fn on_receiver(name: String, receiver_type: String) -> Self {
        Self {
            name,
            imported_mod: None,
            receiver_type: Some(receiver_type),
        }
    }
}

#[derive(Clone, Debug)]
pub(crate) struct ImportTarget {
    pub(crate) name: String,
    pub(crate) module: String,
}

pub(crate) type ImportMap = HashMap<String, ImportTarget>;
