from pathlib import Path
from random import choice
from string import ascii_lowercase

import pytest
from git import Repo


class Wrapper:
    def __init__(self, root_path: Path, name=None, include_dbd=True, **kwargs):
        if name is None:
            name = "test_mod_" + "".join(choice(ascii_lowercase) for _ in range(16))
        self.path = Path(root_path / f"e3-{name}")
        self.name = name

        module_path = (
            name if "E3_MODULE_SRC_PATH" not in kwargs else kwargs["E3_MODULE_SRC_PATH"]
        )
        self.module_dir = self.path / module_path
        self.module_dir.mkdir(parents=True)

        self.makefile = self.path / f"{name}.Makefile"

        makefile = f"""
TOP:=$(CURDIR)

E3_MODULE_NAME:={name}
E3_MODULE_SRC_PATH:={module_path}
E3_MODULE_MAKEFILE:={name}.Makefile

include $(REQUIRE_CONFIG)/CONFIG
include $(REQUIRE_CONFIG)/RULES_SITEMODS
"""
        with open(self.path / "Makefile", "w") as f:
            f.write(makefile)

        module_makefile = """
where_am_I := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
include $(E3_REQUIRE_TOOLS)/driver.makefile
"""
        with open(self.path / f"{name}.Makefile", "w") as f:
            f.write(module_makefile)

        if include_dbd:
            self.add_file("test.dbd")

        Repo.init(self.path)

    def add_file(self, name, makefile_var=None, add_file=True):
        if add_file:
            (self.module_dir / name).touch()
        if makefile_var:
            with open(self.makefile, "a") as f:
                f.write(f"{makefile_var} += {name}")


@pytest.fixture
def wrappers(tmpdir, request):
    class WrapperFactory:
        def get(self):
            """
            Sets up a wrapper with the minimal necessary configuration in order to build a module

            Note that a number of necessary variables are expected to be present in the environment
            """
            temp_wrapper = Wrapper(tmpdir)
            return temp_wrapper.path

    yield WrapperFactory()


@pytest.fixture
def wrapper(wrappers):
    yield wrappers.get()