#!/usr/bin/env bash
# Scenario 04: Class/trait hierarchy
# Question: "What extends BaseService?" / "Who implements AuthProvider?"
#
# Tests: hierarchy query vs grep for class/impl keywords
# Key differentiator: cartog returns structured parent/child pairs

source "$(dirname "$0")/../lib/common.sh"
source "$(dirname "$0")/../lib/compare.sh"

SCENARIO="04_class_hierarchy"

run_scenario() {
    local fixture_name="$1"
    local symbol="$2"
    local grep_pattern="$3"

    local fixture_dir="$BENCH_DIR/fixtures/$fixture_name"

    should_skip_fixture "$fixture_name" && return 0

    echo -e "  ${CYAN}[$fixture_name]${NC} Hierarchy of $symbol?" >&2

    # ── Naive grep: search for class name ──
    run_grep "naive" "$fixture_dir" "grep -rn '$symbol' ."
    local naive_tok=$GREP_TOKENS
    local naive_out="$GREP_OUTPUT"
    local naive_cmds=1

    # ── Best-effort grep: pattern for inheritance ──
    run_grep "best" "$fixture_dir" "grep -rn '$grep_pattern' ."
    local best_tok=$GREP_TOKENS
    local best_out="$GREP_OUTPUT"
    local best_cmds=1

    # ── Cartog ──
    run_cartog_cmd "$fixture_dir" hierarchy "$symbol"
    local cartog_tok=$CARTOG_TOKENS
    local cartog_out="$CARTOG_OUTPUT"
    local cartog_cmds=1

    # ── Recall: check expected hierarchy pairs ──
    # For hierarchy, check both child and parent names appear
    local naive_recall best_recall cartog_recall
    read -r _ _ naive_recall <<< "$(check_recall "$naive_out" "$fixture_name" "$SCENARIO" '.expected[].child')"
    read -r _ _ best_recall <<< "$(check_recall "$best_out" "$fixture_name" "$SCENARIO" '.expected[].child')"
    read -r _ _ cartog_recall <<< "$(check_recall "$CARTOG_JSON_OUTPUT" "$fixture_name" "$SCENARIO" '.expected[].child')"

    print_comparison "$SCENARIO" "$fixture_name" \
        "$naive_tok" "$naive_cmds" "$naive_recall" \
        "$best_tok" "$best_cmds" "$best_recall" \
        "$cartog_tok" "$cartog_cmds" "$cartog_recall"

    emit_result_json "$SCENARIO" "$fixture_name" \
        "$naive_tok" "$naive_recall" \
        "$best_tok" "$best_recall" \
        "$cartog_tok" "$cartog_recall"
}

run_scenario "webapp_py" "BaseService" "class.*BaseService\|class.*(BaseService)\|class.*(AuthService)"
run_scenario "webapp_ts" "BaseService" "class.*BaseService\|extends.*BaseService\|implements.*BaseService"
run_scenario "webapp_rb" "BaseService" "class.*BaseService\|class.*<.*BaseService\|class.*<.*AuthService"
run_scenario "webapp_java" "BaseService" "class.*BaseService\|class.*extends.*BaseService\|class.*extends.*AuthService"
run_scenario "webapp_swift" "BaseService" "class.*BaseService\|class.*:.*BaseService\|class.*:.*AuthService"
run_scenario "webapp_kt" "BaseService" "class.*BaseService\|class.*:.*BaseService\|class.*:.*AuthService"

# PHP has `extends BaseService` subclasses in source, but cartog only partially
# resolves PHP inheritance: the error tree (e.g. TokenError -> App\AppError)
# resolves while service-class extends do not, so this row currently
# under-scores. See "Known cartog gaps" in benchmarks/README.md.
run_scenario "webapp_php" "BaseService" "class.*BaseService\|class.*extends.*BaseService\|class.*extends.*AuthService"

# Rust (traits, not class inheritance) and Go (struct embedding, not
# inheritance) have no subclass hierarchy to resolve, so they are not part of
# this scenario. Rust trait-impl / Go interface-satisfaction discovery is a
# distinct capability cartog does not expose today. See
# "Known cartog gaps" in benchmarks/README.md.
echo -e "  ${YELLOW}[webapp_rs] skipped: Rust uses traits, not class inheritance${NC}" >&2
echo -e "  ${YELLOW}[webapp_go] skipped: Go uses struct embedding, not class inheritance${NC}" >&2
