# Copyright 2015-2016, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#     * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""A setup module for the GRPC Python package."""

import os
import os.path
import shutil
import sys

from distutils import core as _core
from distutils import extension as _extension
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'

PYTHON_STEM = './src/python/grpcio/'
CORE_INCLUDE = ('./include', './',)
BORINGSSL_INCLUDE = ('./third_party/boringssl/include',)

# 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, PYTHON_STEM)

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

LICENSE = '3-clause BSD'

# 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.
BUILD_WITH_CYTHON = os.environ.get('GRPC_PYTHON_BUILD_WITH_CYTHON', 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 to determine whether or not to include the test files in
# the installation.
INSTALL_TESTS = os.environ.get('GRPC_PYTHON_INSTALL_TESTS', False)

CYTHON_EXTENSION_PACKAGE_NAMES = ()

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

EXTENSION_INCLUDE_DIRECTORIES = (
    (PYTHON_STEM,) + CORE_INCLUDE + BORINGSSL_INCLUDE)

EXTENSION_LIBRARIES = ()
if not "darwin" in sys.platform:
    EXTENSION_LIBRARIES += ('rt',)

DEFINE_MACROS = (('OPENSSL_NO_ASM', 1),)

def cython_extensions(package_names, module_names, include_dirs, libraries,
                      define_macros, build_with_cython=False):
  if ENABLE_CYTHON_TRACING:
    define_macros = define_macros + [('CYTHON_TRACE_NOGIL', 1)]
  file_extension = 'pyx' if build_with_cython else 'c'
  module_files = [os.path.join(PYTHON_STEM,
                               name.replace('.', '/') + '.' + file_extension)
                  for name in module_names]
  extensions = [
      _extension.Extension(
          name=module_name,
          sources=[module_file] + grpc_core_dependencies.CORE_SOURCE_FILES,
          include_dirs=include_dirs, libraries=libraries,
          define_macros=define_macros,
      ) for (module_name, module_file) in zip(module_names, module_files)
  ]
  if build_with_cython:
    import Cython.Build
    return Cython.Build.cythonize(
        extensions,
        include_path=include_dirs,
        compiler_directives={'linetrace': bool(ENABLE_CYTHON_TRACING)})
  else:
    return extensions

CYTHON_EXTENSION_MODULES = cython_extensions(
    list(CYTHON_EXTENSION_PACKAGE_NAMES), list(CYTHON_EXTENSION_MODULE_NAMES),
    list(EXTENSION_INCLUDE_DIRECTORIES), list(EXTENSION_LIBRARIES),
    list(DEFINE_MACROS), bool(BUILD_WITH_CYTHON))

PACKAGE_DIRECTORIES = {
    '': PYTHON_STEM,
}

INSTALL_REQUIRES = (
    'enum34>=1.0.4',
    'futures>=2.2.0',
)

SETUP_REQUIRES = (
    'sphinx>=1.3',
) + INSTALL_REQUIRES

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

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

TEST_PACKAGE_DATA = {
    'tests.interop': [
        'credentials/ca.pem',
        'credentials/server1.key',
        'credentials/server1.pem',
    ],
    'tests.protoc_plugin': [
        'protoc_plugin_test.proto',
    ],
    'tests.unit': [
        'credentials/ca.pem',
        'credentials/server1.key',
        'credentials/server1.pem',
    ],
    'grpc._adapter': [
        'credentials/roots.pem'
    ],
}

TESTS_REQUIRE = (
    'oauth2client>=1.4.7',
    'protobuf>=3.0.0a3',
    'coverage>=4.0',
) + INSTALL_REQUIRES

TEST_SUITE = 'tests'
TEST_LOADER = 'tests:Loader'
TEST_RUNNER = 'tests:Runner'

PACKAGE_DATA = {}
if INSTALL_TESTS:
  PACKAGE_DATA = dict(PACKAGE_DATA, **TEST_PACKAGE_DATA)
  PACKAGES = setuptools.find_packages(PYTHON_STEM)
else:
  PACKAGES = setuptools.find_packages(
      PYTHON_STEM, exclude=['tests', 'tests.*'])

setuptools.setup(
    name='grpcio',
    version='0.12.0b5',
    license=LICENSE,
    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,
    tests_require=TESTS_REQUIRE,
    test_suite=TEST_SUITE,
    test_loader=TEST_LOADER,
    test_runner=TEST_RUNNER,
)
