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

# import os
import pytest

import atf


# Setup
@pytest.fixture(scope="module", autouse=True)
def setup():
    atf.require_auto_config(
        "wants to create helpers.conf, helper scripts and reboot script"
    )
    atf.require_config_parameter("NodeFeaturesPlugins", "node_features/helpers")
    atf.require_nodes(1)
    helper_script = make_helper_script()
    feature_helpers_dict = {}
    for i in range(2):
        feature_helpers_dict[f"f{i+1}"] = {"Helper": helper_script}
    atf.require_config_parameter("Feature", feature_helpers_dict, source="helpers")
    atf.require_config_parameter_includes("DebugFlags", "POWER")
    atf.require_config_parameter("RebootProgram", f"{atf.module_tmp_path}/rebooter.sh")
    atf.require_slurm_running()


# Creates the script called by each helper in the helpers.conf
def make_helper_script():
    # Helper variable storage location:
    helpers_variable_file = f"{atf.module_tmp_path}/helper.vars"

    helper_script = f"{atf.module_tmp_path}/helper.sh"
    atf.make_bash_script(
        helper_script,
        f"""
touch {helpers_variable_file}
if [ -n \"$1\" ]; then
    echo $1 > {helpers_variable_file}
fi
cat {helpers_variable_file}""",
    )

    # Set initial active feature as f1 by storing it in the helper variable file
    atf.run_command(f"echo f1 > {helpers_variable_file}", fatal=True, quiet=True)
    atf.run_command(
        f"chmod 0666 {helpers_variable_file}", user="root", fatal=True, quiet=True
    )
    return helper_script


# Creates the rebooter script referenced in slurm.conf that kills and restarts the proper slurmd
def make_rebooter_script(node_name, out_file):
    reboot_file = f"{atf.module_tmp_path}/rebooter.sh"
    slurmd_path = f"{atf.properties['slurm-sbin-dir']}/slurmd -N {node_name}"

    atf.make_bash_script(
        reboot_file,
        f"""
slurmd_pid=$(<"{atf.get_run_dir_path()}/slurmd.{node_name}.pid")
slurmd_start_cmd=$(ps -p $slurmd_pid -o cmd=)
kill $slurmd_pid
echo "slurmd_start_cmd: $slurmd_start_cmd"
($slurmd_start_cmd -b)
sleep 5
while [ $SECONDS -lt 10 ]; do
    if ps -p $(pgrep -f '{slurmd_path}'); then
        echo 'done' > {out_file}
        break
    fi
done
""",
    )

    atf.run_command(f"chmod 0755 {reboot_file}", user="root", fatal=True, quiet=True)


@pytest.fixture(scope="module")
def our_node():
    # Determine our node name and wait until the node is up and at 'idle' state
    node_name = list(atf.nodes.keys())[0]
    atf.repeat_command_until(
        f"sinfo -h -n {node_name} -o %t",
        lambda results: re.search(r"idle", results["stdout"]),
    )
    return node_name


def test_plugin_features(our_node):
    """Verify plugin is enabled and ActiveFeatures != AvailableFeatures"""

    active_feats = atf.get_node_parameter(our_node, "active_features")
    avail_feats = atf.get_node_parameter(our_node, "features")
    assert (
        active_feats != avail_feats
    ), "AvailableFeatures should not equal ActiveFeatures"


def test_request_adds_new_ActiveFeature(our_node):
    """Verify job request with new ActiveFeature restarts, adds new ActiveFeature, and runs"""

    out_file = f"{atf.module_tmp_path}/file.out"
    make_rebooter_script(our_node, out_file)

    # Submit a job with inactive available feature 'f2', should trigger reboot
    atf.submit_job_sbatch(f"--wrap='true' -C f2 -w {our_node}", fatal=True)

    # Wait for output from rebooter script that indicates a successful reboot
    atf.repeat_command_until(
        f"cat {out_file}",
        lambda results: re.search(r"done", results["stdout"]),
        fatal=True,
        timeout=30,
    )

    assert atf.repeat_until(
        lambda: atf.get_node_parameter(our_node, "active_features"),
        lambda f: f == ["f2"],
        timeout=30,
        fatal=True,
    ), "f2 is not included in ActiveFeatures"
