"""
Configuration tools.
"""

import os


def read_pkginfo(dirname, infofile="pkginfo.py", versionfile="version.py",
                 versionattr="__version__", increment="0.1"):
    """
    Read python package information.

    Avoids importing as a module, since that might mean having other stuff
    installed before it needs to be (i.e., at setup stage).

    If the package information defines a version attribute, this is used
    as-is.  Otherwise, the version is extracted from the repository tags if
    possible (see hgtools) and written to a version file for use by the
    package.

    Args:
        dirname: Directory to read/write sources in.
        infofile: Package information file.
        versionfile: File to write version information to.
        versionattr: Info attribute storing the version.
        increment: Version auto-increment (see hgtools).

    Returns:
        Package information dict.
    """

    # Gather settings from the python file.
    info = Pkginfo()
    path = infopath = os.path.join(dirname, infofile)
    if os.path.exists(path):
        info.read(path)

    if versionattr not in info:
        # No version specified.
        version = None
        path = versionpath = os.path.join(dirname, versionfile)

        # Try getting it from repo.
        try:
            from hgtools.managers import MercurialManager
            mgr = MercurialManager()
            version = mgr.get_current_version(increment=increment)

            # Write it to version file, so that package can access it.
            with open(versionpath, "w") as fp:
                fp.write(version_format.format(versionattr, version))

            # Set the version attribute.
            info[versionattr] = version

        except (RuntimeError, ImportError):
            # Nope.  Try the version file.
            if os.path.exists(path):
                print("Not updating '{}' (no hgtools)".format(path))
                info.read(versionpath)

    # If still no version, give up.
    if versionattr not in info:
        raise RuntimeError(fail_message.format(infopath, versionpath))

    version = info[versionattr]
    print("Package version {} (from '{}')\n".format(version, path))
    return info


class Pkginfo(dict):
    "Helper class to get package information from Python sources."

    def read(self, filename):
        with open(filename) as fp:
            exec(fp.read(), self)

    def __getattr__(self, attr):
        return self[attr]


version_format = """# Autogenerated by setup -- do not edit!

{} = '{}'
"""

fail_message = """Can't determine package version

No version was found in either '{}' or '{}'.

If this is a Mercurial clone, you need to install the 'hgtools' module
before running setup.py so that the correct package version can be
determined from the repository.
"""
