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

import atf

# import os
import pytest
import re

user_name = atf.get_user_name()


@pytest.fixture(scope="module", autouse=True)
def setup():
    atf.require_slurm_running()


test_combinations = (
    # in_file, out_file, err_file, out_env, err_env, expect_files, out_result, err_result
    (None, None, None, None, None, True, "slurm-%j.out", "slurm-%j.out"),
    (None, "output", "error", None, None, True, "output", "error"),
    (None, "none", "none", None, None, False, "slurm-%j.out", "slurm-%j.err"),
    (
        None,
        "none",
        "none",
        "slurm-%j.out",
        "slurm-%j.err",
        False,
        "slurm-%j.out",
        "slurm-%j.err",
    ),
    ("input.%%", "output.%%", "error.%%", None, None, True, "output.%%", "error.%%"),
    ("input.%%", None, None, "output.%%", "error.%%", True, "output.%%", "error.%%"),
    (
        "input.j.%j",
        "output.j.%j",
        "error.j.%j",
        None,
        None,
        True,
        "output.j.%j",
        "error.j.%j",
    ),
    (
        "input.j.%j",
        None,
        None,
        "output.j.%j",
        "error.j.%j",
        True,
        "output.j.%j",
        "error.j.%j",
    ),
    (
        "input.u.%u",
        "output.u.%u",
        "error.u.%u",
        None,
        None,
        True,
        "output.u.%u",
        "error.u.%u",
    ),
    (
        "input.u.%u",
        None,
        None,
        "output.u.%u",
        "error.u.%u",
        True,
        "output.u.%u",
        "error.u.%u",
    ),
    (
        r"input\ spaces",
        r"output\ spaces",
        r"error\ spaces",
        None,
        None,
        True,
        r"output\ spaces",
        r"error\ spaces",
    ),
    (
        r"input\ spaces",
        None,
        None,
        r"output\ spaces",
        r"error\ spaces",
        True,
        r"output\ spaces",
        r"error\ spaces",
    ),
)


@pytest.mark.parametrize(
    "in_file,out_file,err_file,out_env,err_env,expect_files,out_result,err_result",
    test_combinations,
)
def test_file_io_options(
    in_file,
    out_file,
    err_file,
    out_env,
    err_env,
    expect_files,
    out_result,
    err_result,
):
    """Create jobs and check if expected output and error files exist.

    Args:
        in_file (string/Path): Desired path of job script. If None, default from file_in() will be used.
        out_file (string/Path): Value passed to "--output" of sbatch. Sbatch argument only used if value is given.
        err_file (string/Path): Value passed to "--error" of sbatch. Sbatch argument only used if value is given.
        out_env (string/Path): Value to set environmental variable "SBATCH_OUTPUT" to. "SBATCH_OUTPUT" is unset if no value is given.
        err_env (string/Path): Value to set environmental variable "SBATCH_ERROR" to. "SBATCH_ERROR" is unset if no value is given.
        expect_files (boolean): If True, tests files were created. If False, tests that files are never created.
        out_result (string/Path): Expected path to output file. File existence only tested if path is given.
        err_result (string/Path): Expected path to error file. File existence only tested if path is given.

    Returns:
        The job id of the sbatch job submitted.
    """

    # Build job script that will make content for both output and error files
    atf.make_bash_script(
        "original_in_file",
        """
        id
        sleep aaa
        """,
    )

    # Rename job script as necessary
    if in_file is None:
        in_file = "original_in_file"
    elif in_file != "original_in_file":
        atf.run_command(f"mv original_in_file {in_file}", fatal=True)

    # Create environment variables variable appropriately
    env_vars = ""
    if out_env:
        env_vars += f"SBATCH_OUTPUT={out_env} "
    if err_env:
        env_vars += f"SBATCH_ERROR={err_env} "

    # Submit sbatch job with appropriate arguments
    job_args = ""
    if out_file:
        job_args += f" --output={out_file}"
    if err_file:
        job_args += f" --error={err_file}"
    job_id = atf.submit_job_sbatch(
        f"{job_args} -t1 -N1 {in_file}", env_vars=env_vars, fatal=True
    )

    # Wait for job to complete
    atf.wait_for_job_state(job_id, "DONE", fatal=True)

    # Make substitutions in result file names, exactly as we expect Slurm to
    if out_result:
        out_result = str(out_result).replace("%j", str(job_id))
        out_result = out_result.replace("%u", user_name)
        out_result = out_result.replace("%%", "%")
        out_result = out_result.replace(r"\ ", " ")
    if err_result:
        err_result = str(err_result).replace("%j", str(job_id))
        err_result = err_result.replace("%u", user_name)
        err_result = err_result.replace("%%", "%")
        err_result = err_result.replace(r"\ ", " ")

    # Check files were created or not, and their contents
    if expect_files:
        if out_result:
            assert atf.wait_for_file(
                out_result
            ), f"Output file {out_result} should be created"

            output = atf.run_command_output(f'cat "{out_result}"', fatal=True)
            assert (
                len(re.findall(r"uid=", output)) == 1
            ), "Couldn't find 'uid=' in output from 'id' call"
        if err_result:
            assert atf.wait_for_file(
                err_result
            ), f"Error file {err_result} should be created"

            errors = atf.run_command_output(f'cat "{err_result}"', fatal=True)
            assert (
                len(re.findall(r"invalid time interval", errors)) == 1
            ), "Couldn't find error in error file from invalid sleep command ('sleep aaa')"
    else:
        if out_result:
            assert not atf.wait_for_file(
                out_result, timeout=5, xfail=True
            ), f"Output file {out_result} should not be created"
        if err_result:
            assert not atf.wait_for_file(
                err_result, timeout=5, xfail=True
            ), f"Error file {err_result} should not be created"
