# Copyright 2021-2022 VMware, Inc.
# SPDX-License-Identifier: Apache-2.0
#
import functools
import logging
import os
import stat
import tempfile
import textwrap

import pytest

try:  # pragma: no cover
    import importlib.metadata

    pkg_version = importlib.metadata.version
except ImportError:  # pragma: no cover
    try:
        import importlib_metadata

        pkg_version = importlib_metadata.version
    except ImportError:  # pragma: no cover
        import pkg_resources

        def pkg_version(package):
            return pkg_resources.get_distribution(package).version


log = logging.getLogger(__name__)


def pkg_version_info(package):
    """
    Return a version info tuple for the given package.
    """
    return tuple(int(part) for part in pkg_version(package).split(".") if part.isdigit())


if pkg_version_info("pytest") >= (6, 2):
    pytest_plugins = ["pytester"]
else:  # pragma: no cover

    @pytest.fixture
    def pytester():
        pytest.skip("The pytester fixture is not available in Pytest < 6.2.0")


class Tempfiles:
    """
    Class which generates temporary files and cleans them when done.
    """

    def __init__(self, request):
        self.request = request

    def makepyfile(self, contents, prefix=None, executable=False):
        """
        Creates a python file and returns it's path.
        """
        tfile = tempfile.NamedTemporaryFile("w", prefix=prefix or "tmp", suffix=".py", delete=False)
        contents = textwrap.dedent(contents.lstrip("\n")).strip()
        tfile.write(contents)
        tfile.close()
        if executable is True:
            st = os.stat(tfile.name)
            os.chmod(tfile.name, st.st_mode | stat.S_IEXEC)
        self.request.addfinalizer(functools.partial(self._delete_temp_file, tfile.name))
        with open(tfile.name, encoding="utf-8") as rfh:
            log.debug(
                "Created python file with contents:\n>>>>> %s >>>>>\n%s\n<<<<< %s <<<<<\n",
                tfile.name,
                rfh.read(),
                tfile.name,
            )
        return tfile.name

    def _delete_temp_file(self, fpath):
        """
        Cleanup the temporary path.
        """
        if os.path.exists(fpath):  # pragma: no branch
            os.unlink(fpath)


@pytest.fixture
def tempfiles(request):
    """
    Temporary files fixture.
    """
    return Tempfiles(request)
