//! Singleton dispatch pin for milestone 24.2's Show class.
//!
//! Asserts that with `prelude.Show` shipping `show` and a user `TShow`
//! shipping `tshow`, the bare method-name dispatcher resolves each via
//! Step-2 singleton (each method has exactly one candidate class globally).

use ailang_check::{build_check_env, check_workspace};
use ailang_surface::load_workspace;
use std::path::PathBuf;

fn fixture_dir() -> PathBuf {
    let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
    d.pop();
    d.pop();
    d.join("examples")
}

#[test]
fn bare_show_routes_to_prelude_show_via_singleton() {
    // Workspace = auto-loaded prelude (containing class Show) plus a
    // non-prelude entry that has zero `Show` declarations of its own.
    // Asserts: env.method_to_candidate_classes["show"] == {"prelude.Show"}
    // (a singleton), so Step-2 of resolve_method_dispatch resolves bare
    // "show" without needing Steps 3-4.
    let ws_path = fixture_dir().join("show_mono_pin_smoke.ail");
    let ws = load_workspace(&ws_path).expect("workspace loads");
    let diags = check_workspace(&ws);
    assert!(diags.is_empty(), "typecheck diagnostics: {diags:#?}");

    let env = build_check_env(&ws);
    let candidates = env
        .method_to_candidate_classes
        .get("show")
        .expect("method 'show' has candidates");
    assert_eq!(
        candidates.len(),
        1,
        "post-24.2-migration, 'show' has exactly one candidate class globally: got {candidates:?}"
    );
    assert!(
        candidates.iter().any(|c| c == "prelude.Show"),
        "candidates do not include prelude.Show: {candidates:?}"
    );
}

#[test]
fn bare_tshow_routes_to_user_tshow_via_singleton() {
    // Workspace = auto-loaded prelude + the migrated 22b1_dup_classmod
    // (which now declares class TShow with method tshow).
    // Asserts: env.method_to_candidate_classes["tshow"] has exactly one
    // candidate (the user TShow), workspace-globally.
    let ws_path = fixture_dir().join("test_22b1_dup_classmod.ail");
    let ws = load_workspace(&ws_path).expect("workspace loads");
    let diags = check_workspace(&ws);
    assert!(diags.is_empty(), "typecheck diagnostics: {diags:#?}");

    let env = build_check_env(&ws);
    let candidates = env
        .method_to_candidate_classes
        .get("tshow")
        .expect("method 'tshow' has candidates");
    assert_eq!(
        candidates.len(),
        1,
        "post-22b-migration, 'tshow' is owned by exactly one class globally: got {candidates:?}"
    );
    assert!(
        candidates.iter().any(|c| c.ends_with(".TShow")),
        "candidates do not include a *.TShow class: {candidates:?}"
    );
}
