#!/usr/bin/env python
"""Setup file of the ``django-lockable`` module. """

import ast
import codecs
import os
from pip.req import parse_requirements
from setuptools import find_packages, setup

# pylint: disable=invalid-name,ungrouped-imports


# Configuration
package_name = 'django_lockable'
long_doc_file = 'README.rst'
classifiers = [
    "Development Status :: 5 - Production/Stable",
    "Operating System :: OS Independent",
    "Intended Audience :: Developers",
    "License :: OSI Approved :: BSD License",
    "Programming Language :: Python :: 3",
    "Programming Language :: Python :: 3.4",
    "Topic :: Software Development :: Libraries",
    "Topic :: Software Development :: Libraries :: Python Modules",
    "Framework :: Django",
    "Framework :: Django :: 1.8",
    "Framework :: Django :: 1.9",
]

# The session argument for the parse_requirements function is available (but
# optional) in pip 1.5, and mandatory in next versions
try:
    from pip.download import PipSession  # pylint: disable=wrong-import-position
except ImportError:
    parse_args = {}
else:
    parse_args = {'session': PipSession()}


def get_requirements(source):
    """Get the requirements to pass to ``install_requires`` from a requirements file."""
    install_reqs = parse_requirements(source, **parse_args)
    return set([str(ir.req) for ir in install_reqs])


class VersionFinder(ast.NodeVisitor):
    """A python parser to extract package info."""

    expected_package_info = {
        '__version__',
        '__author__',
        '__contact__',
        '__homepage__',
        '__license__',
    }

    def __init__(self):
        """Initialize a dict to store package info."""
        self.data = {}

    def visit_Assign(self, node):
        """Save some assigned values."""
        if node.targets[0].id in self.expected_package_info:
            self.data[node.targets[0].id[2:-2]] = node.value.s


def read(*path_parts):
    """Return the content of a file defined by the given path parts."""
    filename = os.path.join(os.path.dirname(__file__), *path_parts)
    with codecs.open(filename, encoding='utf-8') as fp:
        return fp.read()


def find_info(*path_parts):
    """Extract package info from the file defined by the given path parts."""
    finder = VersionFinder()
    node = ast.parse(read(*path_parts))
    finder.visit(node)
    info = finder.data.copy()
    info['docstring'] = ast.get_docstring(node)
    return info


package_info = find_info(package_name, '__init__.py')

setup(
    name=package_name,
    version=package_info['version'],
    packages=find_packages(exclude=['tests']),
    include_package_data=True,
    description=package_info['docstring'].strip().replace("\n", " "),
    long_description=read(long_doc_file),
    url=package_info['homepage'],
    author=package_info['author'],
    author_email=package_info['contact'],
    install_requires=get_requirements('requirements.txt'),
    license=package_info['license'],
    classifiers=classifiers,
)
