# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import sys
import re
import fnmatch

import setuptools
from setuptools import setup
from distutils.core import Command

try:
    import epydoc  # NOQA
    has_epydoc = True
except ImportError:
    has_epydoc = False

# NOTE: Those functions are intentionally moved in-line to prevent setup.py dependening on any
# Libcloud code which depends on libraries such as typing, enum, requests, etc.
# START: Taken From Twisted Python which licensed under MIT license
# https://github.com/powdahound/twisted/blob/master/twisted/python/dist.py
# https://github.com/powdahound/twisted/blob/master/LICENSE

# Names that are excluded from globbing results:
EXCLUDE_NAMES = ['{arch}', 'CVS', '.cvsignore', '_darcs',
                 'RCS', 'SCCS', '.svn']
EXCLUDE_PATTERNS = ['*.py[cdo]', '*.s[ol]', '.#*', '*~', '*.py']


def _filter_names(names):
    """
    Given a list of file names, return those names that should be copied.
    """
    names = [n for n in names
             if n not in EXCLUDE_NAMES]
    # This is needed when building a distro from a working
    # copy (likely a checkout) rather than a pristine export:
    for pattern in EXCLUDE_PATTERNS:
        names = [n for n in names
                 if not fnmatch.fnmatch(n, pattern) and not n.endswith('.py')]
    return names


def relative_to(base, relativee):
    """
    Gets 'relativee' relative to 'basepath'.

    i.e.,

    >>> relative_to('/home/', '/home/radix/')
    'radix'
    >>> relative_to('.', '/home/radix/Projects/Twisted')
    'Projects/Twisted'

    The 'relativee' must be a child of 'basepath'.
    """
    basepath = os.path.abspath(base)
    relativee = os.path.abspath(relativee)
    if relativee.startswith(basepath):
        relative = relativee[len(basepath):]
        if relative.startswith(os.sep):
            relative = relative[1:]
        return os.path.join(base, relative)
    raise ValueError("%s is not a subpath of %s" % (relativee, basepath))


def get_packages(dname, pkgname=None, results=None, ignore=None, parent=None):
    """
    Get all packages which are under dname. This is necessary for
    Python 2.2's distutils. Pretty similar arguments to getDataFiles,
    including 'parent'.
    """
    parent = parent or ""
    prefix = []
    if parent:
        prefix = [parent]
    bname = os.path.basename(dname)
    ignore = ignore or []
    if bname in ignore:
        return []
    if results is None:
        results = []
    if pkgname is None:
        pkgname = []
    subfiles = os.listdir(dname)
    abssubfiles = [os.path.join(dname, x) for x in subfiles]

    if '__init__.py' in subfiles:
        results.append(prefix + pkgname + [bname])
        for subdir in filter(os.path.isdir, abssubfiles):
            get_packages(subdir, pkgname=pkgname + [bname],
                         results=results, ignore=ignore,
                         parent=parent)
    res = ['.'.join(result) for result in results]
    return res


def get_data_files(dname, ignore=None, parent=None):
    """
    Get all the data files that should be included in this distutils Project.

    'dname' should be the path to the package that you're distributing.

    'ignore' is a list of sub-packages to ignore.  This facilitates
    disparate package hierarchies.  That's a fancy way of saying that
    the 'twisted' package doesn't want to include the 'twisted.conch'
    package, so it will pass ['conch'] as the value.

    'parent' is necessary if you're distributing a subpackage like
    twisted.conch.  'dname' should point to 'twisted/conch' and 'parent'
    should point to 'twisted'.  This ensures that your data_files are
    generated correctly, only using relative paths for the first element
    of the tuple ('twisted/conch/*').
    The default 'parent' is the current working directory.
    """
    parent = parent or "."
    ignore = ignore or []
    result = []
    for directory, subdirectories, filenames in os.walk(dname):
        resultfiles = []
        for exname in EXCLUDE_NAMES:
            if exname in subdirectories:
                subdirectories.remove(exname)
        for ig in ignore:
            if ig in subdirectories:
                subdirectories.remove(ig)
        for filename in _filter_names(filenames):
            resultfiles.append(filename)
        if resultfiles:
            for filename in resultfiles:
                file_path = os.path.join(directory, filename)
                if parent:
                    file_path = file_path.replace(parent + os.sep, '')
                result.append(file_path)

    return result
# END: Taken from Twisted


# Different versions of python have different requirements.  We can't use
# libcloud.utils.py3 here because it relies on backports dependency being
# installed / available
PY2 = sys.version_info[0] == 2
PY3 = sys.version_info[0] == 3
PY3_pre_34 = PY3 and sys.version_info < (3, 4)
PY2_pre_27 = PY2 and sys.version_info < (2, 7)
PY2_pre_279 = PY2 and sys.version_info < (2, 7, 9)
PY2_or_3_pre_34 = sys.version_info < (3, 4, 0)

HTML_VIEWSOURCE_BASE = 'https://svn.apache.org/viewvc/libcloud/trunk'
PROJECT_BASE_DIR = 'http://libcloud.apache.org'
TEST_PATHS = ['libcloud/test', 'libcloud/test/common', 'libcloud/test/compute',
              'libcloud/test/storage', 'libcloud/test/loadbalancer',
              'libcloud/test/dns', 'libcloud/test/container',
              'libcloud/test/backup']
DOC_TEST_MODULES = ['libcloud.compute.drivers.dummy',
                    'libcloud.storage.drivers.dummy',
                    'libcloud.dns.drivers.dummy',
                    'libcloud.container.drivers.dummy',
                    'libcloud.backup.drivers.dummy']

SUPPORTED_VERSIONS = ['2.7', 'PyPy', '3.3+']

# NOTE: python_version syntax is only supported when build system has
# setuptools >= 36.2
# For installation, minimum required pip version is 1.4
# Reference: https://hynek.me/articles/conditional-python-dependencies/
INSTALL_REQUIREMENTS = [
    'requests>=2.5.0',
    'backports.ssl_match_hostname ; python_version<"2.7.9"',
    'typing ; python_version<"3.4.0"',
    'enum34 ; python_version<"3.4.0"',
]

EXTRAS_REQUIRE = {}

setuptools_version = tuple(setuptools.__version__.split(".")[0:2])
setuptools_version = tuple([int(c) for c in setuptools_version])

if setuptools_version < (36, 2):
    if 'bdist_wheel' in sys.argv:
        # NOTE: We need to do that because we use universal wheel
        msg = ('Need to use latest version of setuptools when building wheels to ensure included '
               'metadata is correct. Current version: %s' % (setuptools.__version__))
        raise RuntimeError(msg)

if setuptools_version < (18, 0):
    if PY2_pre_279:
        INSTALL_REQUIREMENTS.append('backports.ssl_match_hostname')

    if PY2_or_3_pre_34:
        INSTALL_REQUIREMENTS.append('typing')
        INSTALL_REQUIREMENTS.append('enum34')
else:
    EXTRAS_REQUIRE[":python_version<'2.7.9'"] = ['backports.ssl_match_hostname']
    EXTRAS_REQUIRE[":python_version<'3.4.0'"] = ['typing', 'enum34']

TEST_REQUIREMENTS = [
    'mock',
    'requests_mock',
    'pytest',
    'pytest-runner'
] + INSTALL_REQUIREMENTS

if PY2_pre_279:
    TEST_REQUIREMENTS.append('backports.ssl_match_hostname')

if PY2_pre_27 or PY3_pre_34:
    version = '.'.join([str(x) for x in sys.version_info[:3]])
    print('Version ' + version + ' is not supported. Supported versions are ' +
          ', '.join(SUPPORTED_VERSIONS))
    sys.exit(1)


def read_version_string():
    version = None
    cwd = os.path.dirname(os.path.abspath(__file__))
    version_file = os.path.join(cwd, 'libcloud/__init__.py')

    with open(version_file) as fp:
        content = fp.read()

    match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]",
                      content, re.M)

    if match:
        version = match.group(1)
        return version

    raise Exception('Cannot find version in libcloud/__init__.py')


def forbid_publish():
    argv = sys.argv
    if 'upload'in argv:
        print('You shouldn\'t use upload command to upload a release to PyPi. '
              'You need to manually upload files generated using release.sh '
              'script.\n'
              'For more information, see "Making a release section" in the '
              'documentation')
        sys.exit(1)


class ApiDocsCommand(Command):
    description = "generate API documentation"
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        if not has_epydoc:
            raise RuntimeError('Missing "epydoc" package!')

        os.system(
            'pydoctor'
            ' --add-package=libcloud'
            ' --project-name=libcloud'
            ' --make-html'
            ' --html-viewsource-base="%s"'
            ' --project-base-dir=`pwd`'
            ' --project-url="%s"'
            % (HTML_VIEWSOURCE_BASE, PROJECT_BASE_DIR))


forbid_publish()

needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv)
pytest_runner = ['pytest-runner'] if needs_pytest else []

setup(
    name='apache-libcloud',
    version=read_version_string(),
    description='A standard Python library that abstracts away differences' +
                ' among multiple cloud provider APIs. For more information' +
                ' and documentation, please see http://libcloud.apache.org',
    long_description=open('README.rst').read(),
    author='Apache Software Foundation',
    author_email='dev@libcloud.apache.org',
    install_requires=INSTALL_REQUIREMENTS,
    extras_requires=EXTRAS_REQUIRE,
    python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4",
    packages=get_packages('libcloud'),
    package_dir={
        'libcloud': 'libcloud',
    },
    package_data={
        'libcloud': get_data_files('libcloud', parent='libcloud') + ['py.typed'],
    },
    license='Apache License (2.0)',
    url='http://libcloud.apache.org/',
    setup_requires=pytest_runner,
    tests_require=TEST_REQUIREMENTS,
    cmdclass={
        'apidocs': ApiDocsCommand,
    },
    zip_safe=False,
    classifiers=[
        'Development Status :: 5 - Production/Stable',
        'Environment :: Console',
        'Intended Audience :: Developers',
        'Intended Audience :: System Administrators',
        'License :: OSI Approved :: Apache Software License',
        'Operating System :: OS Independent',
        'Programming Language :: Python',
        'Topic :: Software Development :: Libraries :: Python Modules',
        'Programming Language :: Python :: 2.7',
        'Programming Language :: Python :: 3',
        'Programming Language :: Python :: 3.4',
        'Programming Language :: Python :: 3.5',
        'Programming Language :: Python :: 3.6',
        'Programming Language :: Python :: 3.7',
        'Programming Language :: Python :: 3.8',
        'Programming Language :: Python :: Implementation :: CPython',
        'Programming Language :: Python :: Implementation :: PyPy'
    ]
)
