import os
import toml
from os.path import join, abspath, dirname, isfile, isdir
import fire
from warnings import warn
from .version import __version__
from .update_change_log import update_changelog_interactive
from termcolor import cprint
from .changelog import ChangeLog


PYPROJECT = "pyproject.toml"
RED = "\u001b[31m"
RESET = "\u001b[0m"
VERSIONPY = "version.py"


def err(msg):
    return RED + msg + RESET


here = abspath(dirname(__file__))


class Keats(object):
    def __init__(self, directory=os.getcwd(), filename=PYPROJECT):
        self._path = join(directory, filename)
        self._directory = directory
        if not isfile(self._path):
            warn(
                err(
                    "Cannot run keats. No {} file found in currenct directory.".format(
                        PYPROJECT
                    )
                )
            )

    def _keats(self):
        return self.__class__(here)

    @property
    def config(self):
        return toml.load(self._path)

    def _local_pkg_path(self):
        return self._local_path(self.package())

    def _local_test_path(self):
        return self._local_path("tests")

    def _local_path(self, path):
        return abspath(join(self._directory, path))

    def _get(self, key):
        return self.config["tool"]["poetry"].get(key, None)

    def _cmd(self, cmd):
        cline = "(cd {}; poetry run {})".format(self._directory, cmd)
        os.system(cline)

    def _script(self, name):
        os.system("sh {}".format(join(here, "..", "keat_scripts", name)))

    def release(self):
        return self._script("release.sh")

    def document(self):
        return

    def format(self):
        paths = [self._local_path(p) for p in self.packages() + ["tests"]]
        self._cmd(" ".join(["black"] + paths))

    def packages(self):
        if "packages" in self.config["tool"]["poetry"]:
            pkgs = []
            for pkg in self.config["tool"]["poetry"]["packages"]:
                if "from" in pkg:
                    pkgs.append(join(pkg["from"], pkg["include"]))
                else:
                    pkgs.append(pkg["include"])
        else:
            pkgs = [self._get("name")]
        return pkgs

    def package(self):
        return self.packages()[0]

    def version(self):
        return self._get("version")

    def authors(self):
        return self._get("authors")

    def up(self, version=None):
        if version is None:
            self._write()
        else:
            self.bump(version)

    def bump(self, version=None):
        if version is None:
            self._cmd("poetry version")
        else:
            self._cmd("poetry version {}".format(version))
        self._write()
        return self.changelog().add

    def _version_py(self):
        return join(self._local_pkg_path(), VERSIONPY)

    def info(self):
        toml_info = dict(self.config["tool"]["poetry"])
        pkg_info = {
            "version": toml_info["version"],
            "name": toml_info["name"],
            "authors": toml_info.get("authors", list()),
            "repo": toml_info.get("repo", None),
            "homepage": toml_info.get("homepage", None),
            "description": toml_info.get("description", None),
        }
        return pkg_info

    def _write(self, with_confirm=False):
        pkg_info = self.info()
        path = self._version_py()
        if with_confirm:
            ans = input("Write to '{}'?".format(path))
        else:
            ans = ""
        if ans.strip() == "" or ans.strip().lower() == "y":
            with open(path, "w") as f:
                lines = [
                    "# {}\n".format(VERSIONPY),
                    "# autogenerated by Keats=={}\n".format(__version__),
                ]
                for k, v in pkg_info.items():
                    if isinstance(v, str):
                        v = '"{}"'.format(v)
                    lines.append("__{}__ = {}\n".format(k, v))
                f.writelines(lines)
        else:
            print("no files written")

    def changelog(self):
        return ChangeLog(self)


def main():
    fire.Fire(Keats)
