############################################################################
# Copyright (C) SchedMD LLC.
############################################################################
import time

import pytest

import atf


def _all_jobs_of_state(job_ids=[], desired="RUNNING", timeout=60):
    while True:
        jobs = atf.get_jobs()
        states = [
            jobs[job_id]["JobState"]
            for job_id in jobs
            if not job_ids or job_id in job_ids
        ]
        if all(st == desired for st in states):
            return True
        timeout -= 1
        if timeout <= 0:
            break
        time.sleep(1)
    return False


@pytest.fixture(scope="module", autouse=True)
def setup():
    atf.require_auto_config("Needs to create/reconfigure nodes and partitions")
    atf.require_nodes(1, [("CPUs", 2)])
    atf.require_config_parameter("SelectType", "select/cons_tres")
    atf.require_config_parameter("SelectTypeParameters", "CR_CPU")
    atf.require_slurm_running()


@pytest.fixture(scope="function")
def partition_nodes():
    """Create 2 partitions sharing the same node"""

    nodes = list(atf.get_nodes().keys())
    shared_node = nodes[0]

    atf.run_command(
        f"scontrol create PartitionName=p1 Nodes={shared_node} OverSubscribe=YES",
        fatal=True,
        user=atf.properties["slurm-user"],
    )
    atf.run_command(
        f"scontrol create PartitionName=p2 Nodes={shared_node} OverSubscribe=NO",
        fatal=True,
        user=atf.properties["slurm-user"],
    )

    yield nodes

    atf.cancel_all_jobs()
    atf.run_command(
        "scontrol delete PartitionName=p1",
        user=atf.properties["slurm-user"],
    )
    atf.run_command(
        "scontrol delete PartitionName=p2",
        user=atf.properties["slurm-user"],
    )


@pytest.mark.xfail(
    atf.get_version() < (25, 11),
    reason="Ticket 22228: Fix the 'is-busy' check for a node shared between partitions",
)
def test_overlapping_oversubscribe_differ_sharing_restriction_1(partition_nodes):
    """
    With the select plugin targeting CPU, two partitions sharing a node
    should be able to oversubscribe as long as the other partition does not
    have jobs on the shared node.
    """
    num_oversub_jobs = 2

    # Submit first job to p2 *with* --oversubscribe (despite OverSubscribe=NO)
    job_ids = [
        atf.submit_job_sbatch("-p p2 --oversubscribe --wrap='sleep 60'", fatal=True)
        for _ in range(num_oversub_jobs)
    ]

    # Jobs should run simultaneously
    assert _all_jobs_of_state(job_ids, timeout=60)

    atf.cancel_jobs(job_ids, fatal=True)

    # Submit a job to p1 *without* --oversubscribe
    job_ids = [atf.submit_job_sbatch("-p p1 --wrap='sleep 0'", fatal=True)]

    # Job should complete quickly
    atf.wait_for_job_state(job_ids[0], "COMPLETED", fatal=True, timeout=5)

    # Once again, submit job with oversubscribe to p2 now that p1's job is complete
    job_ids = [
        atf.submit_job_sbatch("-p p2 --oversubscribe --wrap='sleep 60'", fatal=True)
        for _ in range(num_oversub_jobs)
    ]

    # Verify last 'num_oversub_jobs' jobs are running
    assert _all_jobs_of_state(job_ids)
