#!/usr/bin/env python
from distutils.command.build_ext import build_ext
from distutils.errors import CCompilerError, DistutilsExecError, \
    DistutilsPlatformError
import os
import platform
import sys

from setuptools import setup, Extension

# this imports PROJECT, URL, VERSION, AUTHOR, AUTHOR_EMAIL, LICENSE,
# DOWNLOAD_URL
with open('scss/scss_meta.py', 'rb') as f:
    exec(f.read())

# Dependencies
install_requires = ['six']
if sys.version_info < (3, 4):
    install_requires.append('enum34')
    install_requires.append('pathlib')
if sys.version_info < (2, 7):
    install_requires.append('ordereddict')

# fail safe compilation shamelessly stolen from the simplejson
# setup.py file.  Original author: Bob Ippolito

ext_modules = [
    # NOTE: header files are included by MANIFEST.in; Extension does not
    # include headers in an sdist (since they're typically in /usr/lib)
    Extension(
        'scss.grammar._scanner',
        sources=['scss/src/_speedups.c', 'scss/src/block_locator.c',
                 'scss/src/scanner.c', 'scss/src/hashtable.c'],
        libraries=['pcre']
    ),
]

ext_errors = (CCompilerError, DistutilsExecError, DistutilsPlatformError)
if sys.platform == 'win32' and sys.version_info > (2, 6):
    # 2.6's distutils.msvc9compiler can raise an IOError when failing to
    # find the compiler
    ext_errors += (IOError,)


class BuildFailed(Exception):
    pass


class ve_build_ext(build_ext):
    """This class allows C extension building to fail."""

    def run(self):
        try:
            build_ext.run(self)
        except DistutilsPlatformError:
            raise BuildFailed()

    def build_extension(self, ext):
        try:
            build_ext.build_extension(self, ext)
        except ext_errors:
            raise BuildFailed()
        except ValueError:
            # this can happen on Windows 64 bit, see Python issue 7511
            if "'path'" in str(sys.exc_info()[1]):  # works with Python 2 and 3
                raise BuildFailed()
            raise


def echo(msg=''):
    sys.stdout.write(msg + '\n')


def read(fname):
    try:
        with open(os.path.join(os.path.dirname(__file__), fname), 'rb') as f:
            return f.read().decode('utf8').strip()
    except IOError:
        return ''


def run_setup(with_binary):
    if with_binary:
        extra_opts = {}
        extra_opts['ext_modules'] = ext_modules
    else:
        extra_opts = {}
    setup(
        name=PROJECT,
        version=VERSION,
        description=read('DESCRIPTION'),
        long_description=read('README.rst'),
        author=AUTHOR,
        author_email=AUTHOR_EMAIL,
        url=URL,
        zip_safe=False,
        download_url=DOWNLOAD_URL,
        license=LICENSE,
        keywords='css oocss xcss sass scss less precompiler',
        classifiers=[
            "Development Status :: 5 - Production/Stable",
            "Intended Audience :: Developers",
            "License :: OSI Approved :: MIT License",
            "Operating System :: OS Independent",
            "Programming Language :: Python",
            "Programming Language :: Python :: 3",
            "Topic :: Software Development :: Code Generators",
            "Topic :: Text Processing :: Markup",
            "Topic :: Software Development :: Libraries :: Python Modules"
        ],
        install_requires=install_requires,
        packages=[
            'scss',
            'scss.extension',
            'scss.extension.compass',
            'scss.grammar',
        ],
        cmdclass={'build_ext': ve_build_ext},
        entry_points="""
        [console_scripts]
        pyscss = scss.tool:main
        less2scss = scss.less2scss:main
        """,
        **extra_opts
    )


def try_building_extension():
    try:
        run_setup(True)
    except BuildFailed:
        LINE = '=' * 74
        BUILD_EXT_WARNING = 'WARNING: The C extension could not be ' \
                            'compiled, speedups are not enabled.'

        echo(LINE)
        echo(BUILD_EXT_WARNING)
        echo('Failure information, if any, is above.')
        echo('Retrying the build without the C extension now.')
        echo()

        run_setup(False)

        echo(LINE)
        echo(BUILD_EXT_WARNING)
        echo('pyScss will still work fine, but may be slower.')
        echo(
            'The most likely cause is missing PCRE headers; you may need to '
            'install libpcre or libpcre-dev, depending on your platform.'
        )
        echo('Plain-Python installation succeeded.')
        echo(LINE)


if platform.python_implementation() == 'CPython':
    try_building_extension()
else:
    run_setup(False)
