############################################################################
# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
############################################################################
import re

import pytest

import atf


def setup_module():
    atf.require_nodes(1, [("CPUs", 1)])
    atf.require_slurm_running()


def test_listpids():
    """Validate scontrol listpids with numeric job_id, step_id, and non-existent step."""

    file_out = atf.module_tmp_path / "listpids_output"
    script = atf.module_tmp_path / "listpids.sh"
    atf.make_bash_script(
        script,
        """srun sleep 5 &
        sleep 1
        scontrol listpids $SLURM_JOB_ID.10 $SLURMD_NODENAME
        scontrol listpids $SLURM_JOB_ID.0 $SLURMD_NODENAME
        scontrol listpids $SLURM_JOB_ID $SLURMD_NODENAME
        wait""",
    )

    job_id = atf.submit_job_sbatch(f"--output={file_out} {script}", fatal=True)
    atf.wait_for_job_state(job_id, "DONE", fatal=True)
    atf.wait_for_file(file_out, fatal=True)

    output = atf.run_command_output(f"cat {file_out}", fatal=True)

    # Non-existent step .10 should produce an error
    assert re.search(
        rf"StepId={job_id}\.10 does not exist on", output
    ), f"Expected error for non-existent step .10: {output}"

    # listpids for step .0 and for all steps should both show job_id with step 0
    matches = re.findall(rf"{job_id}\s+0\s+0\s+0", output)
    assert (
        len(matches) == 2
    ), f"Expected 2 listpids entries for {job_id} step 0, got {len(matches)}: {output}"


@pytest.mark.skipif(
    atf.get_version("bin/scontrol") < (26, 5),
    reason="Ticket 22180: SLUID availability added in 26.05+",
)
def test_listpids_sluid():
    """Validate scontrol listpids with SLUID and SLUID.stepid."""

    file_out = atf.module_tmp_path / "listpids_sluid_output"
    script = atf.module_tmp_path / "listpids_sluid.sh"
    atf.make_bash_script(
        script,
        """SLUID=$(scontrol -d show job $SLURM_JOB_ID | grep -oP 'SLUID=\\K\\S+')
        srun sleep 3 &
        sleep 1
        scontrol listpids $SLUID.10 $SLURMD_NODENAME
        scontrol listpids $SLUID.0 $SLURMD_NODENAME
        scontrol listpids $SLUID $SLURMD_NODENAME
        wait""",
    )

    job_id = atf.submit_job_sbatch(f"--output={file_out} {script}", fatal=True)
    atf.wait_for_job_state(job_id, "RUNNING", fatal=True)
    sluid = atf.get_job_parameter(job_id, "SLUID")
    assert sluid is not None, f"Job {job_id} has no SLUID"

    atf.wait_for_job_state(job_id, "DONE", fatal=True)
    atf.wait_for_file(file_out, fatal=True)

    output = atf.run_command_output(f"cat {file_out}", fatal=True)

    # Non-existent step .10 should produce an error with SLUID
    assert re.search(
        rf"StepId={re.escape(sluid)}\.10 does not exist on", output
    ), f"Expected error with SLUID for non-existent step .10: {output}"

    # listpids for SLUID.0 and SLUID (all steps) should both show job_id
    # with step 0
    matches = re.findall(rf"{job_id}\s+0\s+0\s+0", output)
    assert (
        len(matches) == 2
    ), f"Expected 2 listpids entries for {job_id} step 0, got {len(matches)}: {output}"
