import os
import pytest
import importlib
import subprocess
import time
import shutil

mod = importlib.import_module("install-mpsd-software-environment")


def test_os_chdir(tmp_path):
    # create a temporary directory for testing
    temp_dir = tmp_path / "test_os_chdir"
    temp_dir.mkdir()

    # initial current working directory
    initial_cwd = os.getcwd()

    # change to the temporary directory using os_chdir
    with mod.os_chdir(str(temp_dir)):
        assert os.getcwd() == str(temp_dir)

    # current working directory should be back to initial directory
    assert os.getcwd() == initial_cwd


def test_prepare_environment(tmp_path):
    # simulate running ./install-software-environment.py --release dev-23a --target-directory /tmp/test_prepare_env
    # prepare_env is run when cmd is not specified, we can test cmd='prepare'  and cmd=None to check both cases

    script_dir = tmp_path / "test_prepare_env"
    spack_environments = "spack-environments"
    mpsd_release_to_test = "dev-23a"
    release_base_dir = script_dir / mpsd_release_to_test
    # check that the test directory does not exist
    assert not script_dir.exists()

    result = mod.prepare_environment(
        mpsd_release=mpsd_release_to_test, script_dir=(script_dir)
    )
    # wait for 20 seconds for the git clone to finish
    # time.sleep(20)
    # check if the directory now is created
    assert release_base_dir.exists()
    # check for spack-environments directory
    assert spack_environments in os.listdir(release_base_dir)
    # check if the git branch is correctly checked out
    assert (
        subprocess.run(
            f"cd {str(release_base_dir/spack_environments)} && git branch",
            shell=True,
            capture_output=True,
        )
        .stdout.decode("utf-8")
        .split("\n")[0]
        == f"* {mpsd_release_to_test}"
    )
    # check that result is a list and contains atleast ['global','foss2021a-mpi'] 
    assert isinstance(result, list)
    assert "global" in result
    assert "foss2021a-mpi" in result


def test_setup_log_cmd(tmp_path):
    # check that logs/install-software-environment.log is updated when the module is run
    log_file = "logs/install-software-environment.log"
    if os.path.exists(log_file):
        initial_bytes = os.path.getsize(log_file)
    else:
        initial_bytes = 0

    # run the prepare_env functionality
    mod.prepare_env(
        toolchain_base_dir=(tmp_path),
        mpsd_spack_ver="dev-23a",
        skip_dir_check=False,
        shared_var=shared_var,
    )

    # check that logs/install-software-environment.log is updated
    assert os.path.exists("logs/install-software-environment.log")
    assert os.path.getsize("logs/install-software-environment.log") > initial_bytes


def test_install_environment(tmp_path):
    # Expect an Exception when wrong toolchains are provided
    with pytest.raises(Exception):
        mod.install_environment(
            mpsd_release="dev-23a",
            toolchains=["wrong-toolchain"],
            script_dir=(tmp_path),
        )
    # Expect an Exception when wrong mpsd_release is provided
    with pytest.raises(Exception):
        mod.install_environment(
            mpsd_release="wrong-mpsd-release",
            toolchains=["foss2021a-mpi"],
            script_dir=(tmp_path),
        )