############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
"""
Test sacct reporting of job oversubscribe and exclusive intent.

Ticket 23303 adds OverSubscribe and Exclusive fields to sacct. These tests
submit completed jobs, wait for slurmdbd to receive the record, then verify
that sacct reports the same token families used by scontrol show job.
"""

import pytest

import atf

JOB_OVERSUBSCRIBE_TOKENS = {"NO", "YES", "OK"}
JOB_EXCLUSIVE_TOKENS = {"NO", "NODE", "USER", "MCS", "TOPO"}


@pytest.fixture(scope="module", autouse=True)
def setup():
    atf.require_version(
        (26, 5),
        "bin/sacct",
        reason="Ticket 23303: sacct OverSubscribe/Exclusive added in 26.05+",
    )
    atf.require_accounting()
    atf.require_slurm_running()


@pytest.fixture(scope="function", autouse=True)
def cancel_jobs(setup):
    yield
    atf.cancel_all_jobs()


def _sacct_oversubscribe_exclusive(job_id):
    """Return (oversubscribe, exclusive), retrying until slurmdbd has the job."""
    output = ""
    for _ in atf.timer():
        output = atf.run_command_output(
            f"sacct -j {job_id} -X --noheader -P -o OverSubscribe,Exclusive",
            fatal=True,
            quiet=True,
        ).strip()
        if output and "|" in output:
            break
    else:
        assert False, (
            f"sacct never returned OverSubscribe|Exclusive for job {job_id}: "
            f"{output!r}"
        )

    return tuple(s.strip() for s in output.split("|", 1))


def _submit_wait_completed(extra_args, script_name):
    script = atf.module_tmp_path / script_name
    atf.make_bash_script(script, "true")
    job_id = atf.submit_job_sbatch(f"{extra_args} {script}", fatal=True)
    atf.wait_for_job_state(job_id, "COMPLETED", fatal=True, timeout=30)
    return job_id


def _assert_sacct_value(field_name, value, expected):
    if isinstance(expected, set):
        assert (
            value in expected
        ), f"sacct {field_name} must be one of {expected}, got {value!r}"
    else:
        assert (
            value == expected
        ), f"sacct {field_name} should be {expected}, got {value!r}"


@pytest.mark.parametrize(
    "extra_args,script_name,expected_oversubscribe,expected_exclusive",
    [
        pytest.param(
            "",
            "sacct_shared_default.sh",
            JOB_OVERSUBSCRIBE_TOKENS,
            JOB_EXCLUSIVE_TOKENS,
            id="default",
        ),
        pytest.param(
            "--exclusive",
            "sacct_shared_exclusive_node.sh",
            "NO",
            "NODE",
            id="exclusive_node",
        ),
        pytest.param(
            "--exclusive=user",
            "sacct_shared_exclusive_user.sh",
            None,
            # select/linear promotes --exclusive=user to whole-node behavior.
            {"USER", "NODE"},
            id="exclusive_user",
        ),
        pytest.param(
            "--exclusive=topo",
            "sacct_shared_exclusive_topo.sh",
            None,
            "TOPO",
            id="exclusive_topo",
        ),
    ],
)
def test_sacct_oversubscribe_exclusive(
    extra_args, script_name, expected_oversubscribe, expected_exclusive
):
    job_id = _submit_wait_completed(extra_args, script_name)
    oversubscribe, exclusive = _sacct_oversubscribe_exclusive(job_id)

    if expected_oversubscribe is not None:
        _assert_sacct_value("OverSubscribe", oversubscribe, expected_oversubscribe)
    _assert_sacct_value("Exclusive", exclusive, expected_exclusive)


@pytest.fixture(scope="function")
def part_for_oversubscribe(setup):
    atf.require_auto_config("Needs to create/delete partition")
    atf.require_nodes(1, [("CPUs", 1)])

    part_name = "test_101_3_oversubscribe"
    nodes = list(atf.get_nodes().keys())
    atf.run_command(
        f"scontrol create PartitionName={part_name} Nodes={nodes[0]} "
        "OverSubscribe=YES:4",
        fatal=True,
        user=atf.properties["slurm-user"],
    )

    yield part_name

    atf.run_command(
        f"scontrol delete PartitionName={part_name}",
        user=atf.properties["slurm-user"],
        quiet=True,
    )


def test_sacct_oversubscribe_yes(part_for_oversubscribe):
    job_id = _submit_wait_completed(
        f"-p {part_for_oversubscribe} --oversubscribe",
        "sacct_oversubscribe_yes.sh",
    )
    oversubscribe, exclusive = _sacct_oversubscribe_exclusive(job_id)

    assert (
        oversubscribe == "YES"
    ), f"--oversubscribe: sacct OverSubscribe should be YES, got {oversubscribe!r}"
    assert (
        exclusive == "NO"
    ), f"--oversubscribe: sacct Exclusive should be NO, got {exclusive!r}"
