# Copyright 2015 gRPC authors.
#
# Licensed 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.

"""A setup module for the GRPC Python package."""
from distutils import cygwinccompiler
from distutils import extension as _extension
from distutils import util
import os
import os.path
import pkg_resources
import platform
import re
import shlex
import shutil
import sys
import sysconfig

import setuptools
from setuptools.command import egg_info

# Redirect the manifest template from MANIFEST.in to PYTHON-MANIFEST.in.
egg_info.manifest_maker.template = 'PYTHON-MANIFEST.in'

PY3 = sys.version_info.major == 3
PYTHON_STEM = os.path.join('src', 'python', 'grpcio')
CORE_INCLUDE = ('include', '.',)
SSL_INCLUDE = (os.path.join('third_party', 'boringssl', 'include'),)
ZLIB_INCLUDE = (os.path.join('third_party', 'zlib'),)
CARES_INCLUDE = (
    os.path.join('third_party', 'cares'),
    os.path.join('third_party', 'cares', 'cares'),)
if 'darwin' in sys.platform:
  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_darwin'),)
if 'freebsd' in sys.platform:
  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_freebsd'),)
if 'linux' in sys.platform:
  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_linux'),)
if 'openbsd' in sys.platform:
  CARES_INCLUDE += (os.path.join('third_party', 'cares', 'config_openbsd'),)
ADDRESS_SORTING_INCLUDE = (os.path.join('third_party', 'address_sorting', 'include'),)
README = os.path.join(PYTHON_STEM, 'README.rst')

# Ensure we're in the proper directory whether or not we're being used by pip.
os.chdir(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, os.path.abspath(PYTHON_STEM))

# Break import-style to ensure we can actually find our in-repo dependencies.
import _spawn_patch
import commands
import grpc_core_dependencies
import grpc_version

_spawn_patch.monkeypatch_spawn()

LICENSE = 'Apache License 2.0'

CLASSIFIERS = [
    'Development Status :: 5 - Production/Stable',
    'Programming Language :: Python',
    'Programming Language :: Python :: 2',
    'Programming Language :: Python :: 2.7',
    'Programming Language :: Python :: 3',
    'Programming Language :: Python :: 3.4',
    'Programming Language :: Python :: 3.5',
    'Programming Language :: Python :: 3.6',
    'License :: OSI Approved :: Apache Software License',
]

# Environment variable to determine whether or not the Cython extension should
# *use* Cython or use the generated C files. Note that this requires the C files
# to have been generated by building first *with* Cython support. Even if this
# is set to false, if the script detects that the generated `.c` file isn't
# present, then it will still attempt to use Cython.
BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', False)

# Export this variable to use the system installation of openssl. You need to
# have the header files installed (in /usr/include/openssl) and during
# runtime, the shared libary must be installed
BUILD_WITH_SYSTEM_OPENSSL = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_OPENSSL',
                                           False)

# Export this variable to use the system installation of zlib. You need to
# have the header files installed (in /usr/include/) and during
# runtime, the shared libary must be installed
BUILD_WITH_SYSTEM_ZLIB = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_ZLIB',
                                        False)

# Export this variable to use the system installation of cares. You need to
# have the header files installed (in /usr/include/) and during
# runtime, the shared libary must be installed
BUILD_WITH_SYSTEM_CARES = os.environ.get('GRPC_PYTHON_BUILD_SYSTEM_CARES',
                                         False)

# Environment variable to determine whether or not to enable coverage analysis
# in Cython modules.
ENABLE_CYTHON_TRACING = os.environ.get(
    'GRPC_PYTHON_ENABLE_CYTHON_TRACING', False)

# Environment variable specifying whether or not there's interest in setting up
# documentation building.
ENABLE_DOCUMENTATION_BUILD = os.environ.get(
    'GRPC_PYTHON_ENABLE_DOCUMENTATION_BUILD', False)

# There are some situations (like on Windows) where CC, CFLAGS, and LDFLAGS are
# entirely ignored/dropped/forgotten by distutils and its Cygwin/MinGW support.
# We use these environment variables to thus get around that without locking
# ourselves in w.r.t. the multitude of operating systems this ought to build on.
# We can also use these variables as a way to inject environment-specific
# compiler/linker flags. We assume GCC-like compilers and/or MinGW as a
# reasonable default.
EXTRA_ENV_COMPILE_ARGS = os.environ.get('GRPC_PYTHON_CFLAGS', None)
EXTRA_ENV_LINK_ARGS = os.environ.get('GRPC_PYTHON_LDFLAGS', None)
if EXTRA_ENV_COMPILE_ARGS is None:
  EXTRA_ENV_COMPILE_ARGS = ' -std=c++11'
  if 'win32' in sys.platform and sys.version_info < (3, 5):
    EXTRA_ENV_COMPILE_ARGS += ' -D_hypot=hypot'
    # We use define flags here and don't directly add to DEFINE_MACROS below to
    # ensure that the expert user/builder has a way of turning it off (via the
    # envvars) without adding yet more GRPC-specific envvars.
    # See https://sourceforge.net/p/mingw-w64/bugs/363/
    if '32' in platform.architecture()[0]:
      EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime32 -D_timeb=__timeb32 -D_ftime_s=_ftime32_s'
    else:
      EXTRA_ENV_COMPILE_ARGS += ' -D_ftime=_ftime64 -D_timeb=__timeb64'
  elif "linux" in sys.platform:
    EXTRA_ENV_COMPILE_ARGS += ' -std=gnu99 -fvisibility=hidden -fno-wrapv -fno-exceptions'
  elif "darwin" in sys.platform:
    EXTRA_ENV_COMPILE_ARGS += ' -fvisibility=hidden -fno-wrapv -fno-exceptions'
EXTRA_ENV_COMPILE_ARGS += ' -DPB_FIELD_16BIT'

if EXTRA_ENV_LINK_ARGS is None:
  EXTRA_ENV_LINK_ARGS = ''
  if "linux" in sys.platform or "darwin" in sys.platform:
    EXTRA_ENV_LINK_ARGS += ' -lpthread'
  elif "win32" in sys.platform and sys.version_info < (3, 5):
    msvcr = cygwinccompiler.get_msvcr()[0]
    # TODO(atash) sift through the GCC specs to see if libstdc++ can have any
    # influence on the linkage outcome on MinGW for non-C++ programs.
    EXTRA_ENV_LINK_ARGS += (
        ' -static-libgcc -static-libstdc++ -mcrtdll={msvcr} '
        '-static'.format(msvcr=msvcr))
  if "linux" in sys.platform:
    EXTRA_ENV_LINK_ARGS += ' -Wl,-wrap,memcpy  -static-libgcc'

EXTRA_COMPILE_ARGS = shlex.split(EXTRA_ENV_COMPILE_ARGS)
EXTRA_LINK_ARGS = shlex.split(EXTRA_ENV_LINK_ARGS)

CYTHON_EXTENSION_PACKAGE_NAMES = ()

CYTHON_EXTENSION_MODULE_NAMES = ('grpc._cython.cygrpc',)

CYTHON_HELPER_C_FILES = ()

CORE_C_FILES = tuple(grpc_core_dependencies.CORE_SOURCE_FILES)
if "win32" in sys.platform:
  CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES)

if BUILD_WITH_SYSTEM_OPENSSL:
  CORE_C_FILES = filter(lambda x: 'third_party/boringssl' not in x, CORE_C_FILES)
  CORE_C_FILES = filter(lambda x: 'src/boringssl' not in x, CORE_C_FILES)
  SSL_INCLUDE = (os.path.join('/usr', 'include', 'openssl'),)

if BUILD_WITH_SYSTEM_ZLIB:
  CORE_C_FILES = filter(lambda x: 'third_party/zlib' not in x, CORE_C_FILES)
  ZLIB_INCLUDE = (os.path.join('/usr', 'include'),)

if BUILD_WITH_SYSTEM_CARES:
  CORE_C_FILES = filter(lambda x: 'third_party/cares' not in x, CORE_C_FILES)
  CARES_INCLUDE = (os.path.join('/usr', 'include'),)

EXTENSION_INCLUDE_DIRECTORIES = (
    (PYTHON_STEM,) + CORE_INCLUDE + SSL_INCLUDE + ZLIB_INCLUDE +
    CARES_INCLUDE + ADDRESS_SORTING_INCLUDE)

EXTENSION_LIBRARIES = ()
if "linux" in sys.platform:
  EXTENSION_LIBRARIES += ('rt',)
if not "win32" in sys.platform:
  EXTENSION_LIBRARIES += ('m',)
if "win32" in sys.platform:
  EXTENSION_LIBRARIES += ('advapi32', 'ws2_32',)
if BUILD_WITH_SYSTEM_OPENSSL:
  EXTENSION_LIBRARIES += ('ssl', 'crypto',)
if BUILD_WITH_SYSTEM_ZLIB:
  EXTENSION_LIBRARIES += ('z',)
if BUILD_WITH_SYSTEM_CARES:
  EXTENSION_LIBRARIES += ('cares',)

DEFINE_MACROS = (
    ('OPENSSL_NO_ASM', 1), ('_WIN32_WINNT', 0x600),
    ('GPR_BACKWARDS_COMPATIBILITY_MODE', 1))
if "win32" in sys.platform:
  # TODO(zyc): Re-enble c-ares on x64 and x86 windows after fixing the
  # ares_library_init compilation issue
  DEFINE_MACROS += (('WIN32_LEAN_AND_MEAN', 1), ('CARES_STATICLIB', 1),
                    ('GRPC_ARES', 0), ('NTDDI_VERSION', 0x06000000),
                    ('NOMINMAX', 1),)
  if '64bit' in platform.architecture()[0]:
    DEFINE_MACROS += (('MS_WIN64', 1),)
  elif sys.version_info >= (3, 5):
    # For some reason, this is needed to get access to inet_pton/inet_ntop
    # on msvc, but only for 32 bits
    DEFINE_MACROS += (('NTDDI_VERSION', 0x06000000),)
else:
  DEFINE_MACROS += (('HAVE_CONFIG_H', 1), ('GRPC_ENABLE_FORK_SUPPORT', 1),)

LDFLAGS = tuple(EXTRA_LINK_ARGS)
CFLAGS = tuple(EXTRA_COMPILE_ARGS)
if "linux" in sys.platform or "darwin" in sys.platform:
  pymodinit_type = 'PyObject*' if PY3 else 'void'
  pymodinit = 'extern "C" __attribute__((visibility ("default"))) {}'.format(pymodinit_type)
  DEFINE_MACROS += (('PyMODINIT_FUNC', pymodinit),)
  DEFINE_MACROS += (('GRPC_POSIX_FORK_ALLOW_PTHREAD_ATFORK', 1),)

# By default, Python3 distutils enforces compatibility of
# c plugins (.so files) with the OSX version Python3 was built with.
# For Python3.4, this is OSX 10.6, but we need Thread Local Support (__thread)
if 'darwin' in sys.platform and PY3:
  mac_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
  if mac_target and (pkg_resources.parse_version(mac_target) <
                     pkg_resources.parse_version('10.7.0')):
    os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.7'
    os.environ['_PYTHON_HOST_PLATFORM'] = re.sub(
        r'macosx-[0-9]+\.[0-9]+-(.+)',
        r'macosx-10.7-\1',
        util.get_platform())

def cython_extensions_and_necessity():
  cython_module_files = [os.path.join(PYTHON_STEM,
                               name.replace('.', '/') + '.pyx')
                  for name in CYTHON_EXTENSION_MODULE_NAMES]
  config = os.environ.get('CONFIG', 'opt')
  prefix = 'libs/' + config + '/'
  if "darwin" in sys.platform:
    extra_objects = [prefix + 'libares.a',
                     prefix + 'libboringssl.a',
                     prefix + 'libgpr.a',
                     prefix + 'libgrpc.a']
    core_c_files = []
  else:
    core_c_files = list(CORE_C_FILES)
    extra_objects = []
  extensions = [
      _extension.Extension(
          name=module_name,
          sources=[module_file] + list(CYTHON_HELPER_C_FILES) + core_c_files,
          include_dirs=list(EXTENSION_INCLUDE_DIRECTORIES),
          libraries=list(EXTENSION_LIBRARIES),
          define_macros=list(DEFINE_MACROS),
          extra_objects=extra_objects,
          extra_compile_args=list(CFLAGS),
          extra_link_args=list(LDFLAGS),
      ) for (module_name, module_file) in zip(list(CYTHON_EXTENSION_MODULE_NAMES), cython_module_files)
  ]
  need_cython = BUILD_WITH_CYTHON
  if not BUILD_WITH_CYTHON:
    need_cython = need_cython or not commands.check_and_update_cythonization(extensions)
  return commands.try_cythonize(extensions, linetracing=ENABLE_CYTHON_TRACING, mandatory=BUILD_WITH_CYTHON), need_cython

CYTHON_EXTENSION_MODULES, need_cython = cython_extensions_and_necessity()

PACKAGE_DIRECTORIES = {
    '': PYTHON_STEM,
}

INSTALL_REQUIRES = (
    'six>=1.5.2',
)

if not PY3:
  INSTALL_REQUIRES += ('futures>=2.2.0', 'enum34>=1.0.4')

SETUP_REQUIRES = INSTALL_REQUIRES + (
    'sphinx>=1.3',
    'sphinx_rtd_theme>=0.1.8',
    'six>=1.10',
  ) if ENABLE_DOCUMENTATION_BUILD else ()

try:
  import Cython
except ImportError:
  if BUILD_WITH_CYTHON:
    sys.stderr.write(
      "You requested a Cython build via GRPC_PYTHON_BUILD_WITH_CYTHON, "
      "but do not have Cython installed. We won't stop you from using "
      "other commands, but the extension files will fail to build.\n")
  elif need_cython:
    sys.stderr.write(
        'We could not find Cython. Setup may take 10-20 minutes.\n')
    SETUP_REQUIRES += ('cython>=0.23',)

COMMAND_CLASS = {
    'doc': commands.SphinxDocumentation,
    'build_project_metadata': commands.BuildProjectMetadata,
    'build_py': commands.BuildPy,
    'build_ext': commands.BuildExt,
    'gather': commands.Gather,
}

# Ensure that package data is copied over before any commands have been run:
credentials_dir = os.path.join(PYTHON_STEM, 'grpc', '_cython', '_credentials')
try:
  os.mkdir(credentials_dir)
except OSError:
  pass
shutil.copyfile(os.path.join('etc', 'roots.pem'),
                os.path.join(credentials_dir, 'roots.pem'))

PACKAGE_DATA = {
    # Binaries that may or may not be present in the final installation, but are
    # mentioned here for completeness.
    'grpc._cython': [
        '_credentials/roots.pem',
        '_windows/grpc_c.32.python',
        '_windows/grpc_c.64.python',
    ],
}
PACKAGES = setuptools.find_packages(PYTHON_STEM)

setuptools.setup(
  name='grpcio',
  version=grpc_version.VERSION,
  description='HTTP/2-based RPC framework',
  author='The gRPC Authors',
  author_email='grpc-io@googlegroups.com',
  url='https://grpc.io',
  license=LICENSE,
  classifiers=CLASSIFIERS,
  long_description=open(README).read(),
  ext_modules=CYTHON_EXTENSION_MODULES,
  packages=list(PACKAGES),
  package_dir=PACKAGE_DIRECTORIES,
  package_data=PACKAGE_DATA,
  install_requires=INSTALL_REQUIRES,
  setup_requires=SETUP_REQUIRES,
  cmdclass=COMMAND_CLASS,
)
