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

import pytest

import atf

test_name = os.path.splitext(os.path.basename(__file__))[0]
partitions = [f"{test_name}_part{i}" for i in range(3)]
acct = f"{test_name}_acct"
resv_name = f"{test_name}_resv"
testuser = atf.properties["test-user"]


@pytest.fixture(scope="module", autouse=True)
def setup():
    atf.require_version(
        (25, 11),
        "bin/scontrol",
        reason="Creating reservations with AllowedPartition= added in scontrol 25.11",
    )
    atf.require_accounting(True)

    atf.require_slurm_running()


@pytest.fixture(scope="module", autouse=True)
def setup_db():

    # Create test Partitions
    for part in partitions:
        atf.run_command(
            f"scontrol create PartitionName={part} Nodes=ALL",
            user=atf.properties["slurm-user"],
            fatal=True,
        )

    yield

    for part in partitions:
        atf.run_command(
            f"scontrol delete PartitionName={part}",
            user=atf.properties["slurm-user"],
            quiet=True,
        )


@pytest.fixture(scope="function")
def resv(request):
    part_access = f"AllowedPartition={partitions[0]}"
    if hasattr(request, "param"):
        part_access = request.param

    result = atf.run_command(
        f"scontrol create ReservationName={resv_name} {part_access} Start=now Duration=1 NodeCnt=1",
        user=atf.properties["slurm-user"],
    )
    assert result["exit_code"] == 0, "Couldn't create the reservation!"

    yield resv_name

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


def test_invalid_args(resv):
    """Test that invalid configurations are rejected"""

    # Mix allow and deny syntax
    part_access = f"AllowedPartitions={partitions[0]},-{partitions[1]}"
    result = atf.run_command(
        f"scontrol create ReservationName=invalid_resv {part_access} Start=now Duration=1 Nodecnt=1",
        user=atf.properties["slurm-user"],
    )
    assert (
        result["exit_code"] != 0
    ), "Creating reservation with allowed and denied partitions should fail"

    # Default reservation only allows partition 0
    # Clear all partition access control
    result = atf.run_command(
        f"scontrol update reservation ReservationName={resv} AllowedPartitions-={partitions[0]}",
        user=atf.properties["slurm-user"],
    )
    assert (
        result["exit_code"] != 0
    ), "Updating reservation to clear all partitions should fail"

    # Change from allow list to deny list
    result = atf.run_command(
        f"scontrol update reservation ReservationName={resv} AllowedPartitions=-{partitions[0]}",
        user=atf.properties["slurm-user"],
    )
    assert (
        result["exit_code"] != 0
    ), "Updating reservation from allow list to deny list should fail"


tests = [
    {
        "part_access": f"AllowedPartitions={partitions[0]}",
        "expected": [0],
        "name": "=0",
    },
    {
        "part_access": f"AllowedPartitions={partitions[0]},{partitions[1]}",
        "expected": [0, 1],
        "name": "=0,1",
    },
    {
        "part_access": f"AllowedPartitions=-{partitions[0]}",
        "expected": [1, 2],
        "name": "=-0",
    },
    {
        "part_access": f"AllowedPartitions=-{partitions[0]},-{partitions[1]}",
        "expected": [2],
        "name": "=-0,-1",
    },
    {
        "part_access": f"AllowedPartitions-={partitions[0]},{partitions[1]}",
        "expected": [2],
        "name": "-=0,1",
    },
]

args = [(x["part_access"], x["expected"]) for x in tests]
ids = [x["name"] for x in tests]


def assert_resv_access(resv, part, is_allowed):
    result = atf.run_command(
        f"srun -N1 --reservation={resv} --partition={part} true",
    )
    if is_allowed:
        assert (
            result["exit_code"] == 0
        ), "ExitCode wasn't 0. The job should not have been denied!"
        assert (
            "Problem using reservation" not in result["stderr"]
        ), "The job should not have been denied for user!"
    else:
        assert (
            result["exit_code"] != 0
        ), "ExitCode was 0. The job should have been denied!"


def assert_resv_access_each(resv, expect):
    # Try to run a job in each partition
    for i in range(len(partitions)):
        part = partitions[i]
        assert_resv_access(resv, part, i in expect)


@pytest.mark.parametrize("resv, expect", args, indirect=["resv"], ids=ids)
def test_reservation_partition(resv, expect):
    """Test that a reservation created with AllowedPartitions= restricts access correctly"""

    assert_resv_access_each(resv, expect)


def test_reservation_partition_any(resv):
    """Test that a job may use reservations when any partition is allowed"""

    # Default reservation only allows part 0
    assert_resv_access_each(resv, [0])

    assert_resv_access(resv, f"{partitions[0]},{partitions[1]}", True)
    assert_resv_access(resv, f"{partitions[0]},{partitions[2]}", True)

    assert_resv_access(resv, f"{partitions[1]},{partitions[2]}", False)


def test_reservation_partition_update(resv):
    """Test that updating a reservation's AllowedPartitions= restricts access correctly"""

    # Add part 1
    atf.run_command(
        f"scontrol update ReservationName={resv} AllowedPartitions+={partitions[1]}",
        user=atf.properties["slurm-user"],
        fatal=True,
    )
    assert_resv_access_each(resv, [0, 1])

    # Remove part 0
    atf.run_command(
        f"scontrol update ReservationName={resv} AllowedPartitions-={partitions[0]}",
        user=atf.properties["slurm-user"],
        fatal=True,
    )
    assert_resv_access_each(resv, [1])

    # Set to part 2
    atf.run_command(
        f"scontrol update ReservationName={resv} AllowedPartitions={partitions[2]}",
        user=atf.properties["slurm-user"],
        fatal=True,
    )
    assert_resv_access_each(resv, [2])
