import os
from setuptools import setup, Command


class ConfigExporter(Command):
    HEAD = (
        "# Autogenerated by setup.py from setup.cfg. "
        "Remove this line if you do not want this file to be overwritten by autogen."
    )
    _config = None

    @staticmethod
    def _get_config():
        if ConfigExporter._config is None:
            import configparser

            ConfigExporter._config = configparser.ConfigParser()
            ConfigExporter._config.read("setup.cfg")
        return ConfigExporter._config


class Conda(ConfigExporter):
    """
    Helper class for building conda packages.
    """

    user_options = [
        ("refresh", False, "Refresh conda_build_config.yaml"),
    ]

    def run(self):
        if self.refresh:
            self.refresh_conda_build_config()

    def refresh_conda_build_config(self):
        """
        Refresh conda_build_config.yaml.
        """
        path = "conda_build_config.yaml"
        if os.path.exists(path):
            with open(path, "r") as f:
                line = f.readline()
                if line.startswith(self.HEAD[:20]):
                    quit("User defined conda_build.config.yaml.")
        with open(path, "w") as f:
            f.write(self.HEAD)
            f.write("\n")


class Requirements(ConfigExporter):
    """
    Externalize requirements so that you are able to install e.g. from conda install --file
    """

    user_options = [
        ("extra=", None, "Extra to add to requirements"),
    ]

    def initialize_options(self):
        self.extra = None

    def finalize_options(self):
        if self.extra is not None:
            config = self._get_config()
            assert self.extra in config["options.extras_require"]

    def run(self):
        self.externalize()

    @staticmethod
    def _write_dependencies(buf, deps):
        if isinstance(deps, str):
            deps = deps.split("\n")
        deps = [dep for dep in deps if dep]
        buf.write("\n".join(deps))
        buf.write("\n")

    def externalize(self):
        path = "requirements.txt"
        if os.path.exists(path):
            with open(path, "r") as f:
                line = f.readline()
                if not line.startswith(self.HEAD[:20]):
                    quit("User defined requirements already existing.")

        with open(path, "w") as f:
            f.write(self.HEAD)
            f.write("\n")

            config = self._get_config()

            deps = config["options"]["install_requires"]
            deps = self._write_dependencies(f, deps)

            if self.extra is not None:
                f.write("# extra: " + self.extra + "\n")
                deps = config["options.extras_require"][self.extra]
                deps = self._write_dependencies(f, deps)


setup(
    version="0.7.10",
    cmdclass={
        "requirements": Requirements,
        "conda": Conda,
    },
)
