# 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.
"""Provides distutils command classes for the GRPC Python setup process."""

import distutils
import glob
import os
import os.path
import platform
import re
import shutil
import subprocess
import sys
import traceback

import setuptools
from setuptools.command import build_ext
from setuptools.command import build_py
from setuptools.command import easy_install
from setuptools.command import install
from setuptools.command import test

import support

PYTHON_STEM = os.path.dirname(os.path.abspath(__file__))
GRPC_STEM = os.path.abspath(PYTHON_STEM + '../../../../')
PROTO_STEM = os.path.join(GRPC_STEM, 'src', 'proto')
PROTO_GEN_STEM = os.path.join(GRPC_STEM, 'src', 'python', 'gens')
CYTHON_STEM = os.path.join(PYTHON_STEM, 'grpc', '_cython')

CONF_PY_ADDENDUM = """
extensions.append('sphinx.ext.napoleon')
napoleon_google_docstring = True
napoleon_numpy_docstring = True
napoleon_include_special_with_doc = True

html_theme = 'sphinx_rtd_theme'
copyright = "2016, The gRPC Authors"
"""

API_GLOSSARY = """

Glossary
================

.. glossary::

  metadatum
    A key-value pair included in the HTTP header.  It is a 
    2-tuple where the first entry is the key and the
    second is the value, i.e. (key, value).  The metadata key is an ASCII str,
    and must be a valid HTTP header name.  The metadata value can be
    either a valid HTTP ASCII str, or bytes.  If bytes are provided,
    the key must end with '-bin', i.e.
    ``('binary-metadata-bin', b'\\x00\\xFF')``

  metadata
    A sequence of metadatum.
"""


class CommandError(Exception):
    """Simple exception class for GRPC custom commands."""


# TODO(atash): Remove this once PyPI has better Linux bdist support. See
# https://bitbucket.org/pypa/pypi/issues/120/binary-wheels-for-linux-are-not-supported
def _get_grpc_custom_bdist(decorated_basename, target_bdist_basename):
    """Returns a string path to a bdist file for Linux to install.

  If we can retrieve a pre-compiled bdist from online, uses it. Else, emits a
  warning and builds from source.
  """
    # TODO(atash): somehow the name that's returned from `wheel` is different
    # between different versions of 'wheel' (but from a compatibility standpoint,
    # the names are compatible); we should have some way of determining name
    # compatibility in the same way `wheel` does to avoid having to rename all of
    # the custom wheels that we build/upload to GCS.

    # Break import style to ensure that setup.py has had a chance to install the
    # relevant package.
    from six.moves.urllib import request
    decorated_path = decorated_basename + GRPC_CUSTOM_BDIST_EXT
    try:
        url = BINARIES_REPOSITORY + '/{target}'.format(target=decorated_path)
        bdist_data = request.urlopen(url).read()
    except IOError as error:
        raise CommandError('{}\n\nCould not find the bdist {}: {}'.format(
            traceback.format_exc(), decorated_path, error.message))
    # Our chosen local bdist path.
    bdist_path = target_bdist_basename + GRPC_CUSTOM_BDIST_EXT
    try:
        with open(bdist_path, 'w') as bdist_file:
            bdist_file.write(bdist_data)
    except IOError as error:
        raise CommandError('{}\n\nCould not write grpcio bdist: {}'
                           .format(traceback.format_exc(), error.message))
    return bdist_path


class SphinxDocumentation(setuptools.Command):
    """Command to generate documentation via sphinx."""

    description = 'generate sphinx documentation'
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        # We import here to ensure that setup.py has had a chance to install the
        # relevant package eggs first.
        import sphinx
        import sphinx.apidoc
        metadata = self.distribution.metadata
        src_dir = os.path.join(PYTHON_STEM, 'grpc')
        sys.path.append(src_dir)
        sphinx.apidoc.main([
            '', '--force', '--full', '-H', metadata.name, '-A', metadata.author,
            '-V', metadata.version, '-R', metadata.version, '-o',
            os.path.join('doc', 'src'), src_dir
        ])
        conf_filepath = os.path.join('doc', 'src', 'conf.py')
        with open(conf_filepath, 'a') as conf_file:
            conf_file.write(CONF_PY_ADDENDUM)
        glossary_filepath = os.path.join('doc', 'src', 'grpc.rst')
        with open(glossary_filepath, 'a') as glossary_filepath:
            glossary_filepath.write(API_GLOSSARY)
        sphinx.main(
            ['', os.path.join('doc', 'src'), os.path.join('doc', 'build')])


class BuildProjectMetadata(setuptools.Command):
    """Command to generate project metadata in a module."""

    description = 'build grpcio project metadata files'
    user_options = []

    def initialize_options(self):
        pass

    def finalize_options(self):
        pass

    def run(self):
        with open(os.path.join(PYTHON_STEM, 'grpc/_grpcio_metadata.py'),
                  'w') as module_file:
            module_file.write('__version__ = """{}"""'.format(
                self.distribution.get_version()))


class BuildPy(build_py.build_py):
    """Custom project build command."""

    def run(self):
        self.run_command('build_project_metadata')
        build_py.build_py.run(self)


def _poison_extensions(extensions, message):
    """Includes a file that will always fail to compile in all extensions."""
    poison_filename = os.path.join(PYTHON_STEM, 'poison.c')
    with open(poison_filename, 'w') as poison:
        poison.write('#error {}'.format(message))
    for extension in extensions:
        extension.sources = [poison_filename]


def check_and_update_cythonization(extensions):
    """Replace .pyx files with their generated counterparts and return whether or
     not cythonization still needs to occur."""
    for extension in extensions:
        generated_pyx_sources = []
        other_sources = []
        for source in extension.sources:
            base, file_ext = os.path.splitext(source)
            if file_ext == '.pyx':
                generated_pyx_source = next((base + gen_ext
                                             for gen_ext in ('.c', '.cpp',)
                                             if os.path.isfile(base + gen_ext)),
                                            None)
                if generated_pyx_source:
                    generated_pyx_sources.append(generated_pyx_source)
                else:
                    sys.stderr.write('Cython-generated files are missing...\n')
                    return False
            else:
                other_sources.append(source)
        extension.sources = generated_pyx_sources + other_sources
    sys.stderr.write('Found cython-generated files...\n')
    return True


def try_cythonize(extensions, linetracing=False, mandatory=True):
    """Attempt to cythonize the extensions.

  Args:
    extensions: A list of `distutils.extension.Extension`.
    linetracing: A bool indicating whether or not to enable linetracing.
    mandatory: Whether or not having Cython-generated files is mandatory. If it
      is, extensions will be poisoned when they can't be fully generated.
  """
    try:
        # Break import style to ensure we have access to Cython post-setup_requires
        import Cython.Build
    except ImportError:
        if mandatory:
            sys.stderr.write(
                "This package needs to generate C files with Cython but it cannot. "
                "Poisoning extension sources to disallow extension commands...")
            _poison_extensions(
                extensions,
                "Extensions have been poisoned due to missing Cython-generated code."
            )
        return extensions
    cython_compiler_directives = {}
    if linetracing:
        additional_define_macros = [('CYTHON_TRACE_NOGIL', '1')]
        cython_compiler_directives['linetrace'] = True
    return Cython.Build.cythonize(
        extensions,
        include_path=[
            include_dir
            for extension in extensions
            for include_dir in extension.include_dirs
        ] + [CYTHON_STEM],
        compiler_directives=cython_compiler_directives)


class BuildExt(build_ext.build_ext):
    """Custom build_ext command to enable compiler-specific flags."""

    C_OPTIONS = {
        'unix': ('-pthread',),
        'msvc': (),
    }
    LINK_OPTIONS = {}

    def build_extensions(self):
        if "darwin" in sys.platform:
            config = os.environ.get('CONFIG', 'opt')
            target_path = os.path.abspath(
                os.path.join(
                    os.path.dirname(os.path.realpath(__file__)), '..', '..',
                    '..', 'libs', config))
            targets = [
                os.path.join(target_path, 'libboringssl.a'),
                os.path.join(target_path, 'libares.a'),
                os.path.join(target_path, 'libgpr.a'),
                os.path.join(target_path, 'libgrpc.a')
            ]
            make_process = subprocess.Popen(
                ['make'] + targets,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE)
            make_out, make_err = make_process.communicate()
            if make_out and make_process.returncode != 0:
                sys.stdout.write(str(make_out) + '\n')
            if make_err:
                sys.stderr.write(str(make_err) + '\n')
            if make_process.returncode != 0:
                raise Exception("make command failed!")

        compiler = self.compiler.compiler_type
        if compiler in BuildExt.C_OPTIONS:
            for extension in self.extensions:
                extension.extra_compile_args += list(
                    BuildExt.C_OPTIONS[compiler])
        if compiler in BuildExt.LINK_OPTIONS:
            for extension in self.extensions:
                extension.extra_link_args += list(
                    BuildExt.LINK_OPTIONS[compiler])
        if not check_and_update_cythonization(self.extensions):
            self.extensions = try_cythonize(self.extensions)
        try:
            build_ext.build_ext.build_extensions(self)
        except Exception as error:
            formatted_exception = traceback.format_exc()
            support.diagnose_build_ext_error(self, error, formatted_exception)
            raise CommandError(
                "Failed `build_ext` step:\n{}".format(formatted_exception))


class Gather(setuptools.Command):
    """Command to gather project dependencies."""

    description = 'gather dependencies for grpcio'
    user_options = [
        ('test', 't', 'flag indicating to gather test dependencies'),
        ('install', 'i', 'flag indicating to gather install dependencies')
    ]

    def initialize_options(self):
        self.test = False
        self.install = False

    def finalize_options(self):
        # distutils requires this override.
        pass

    def run(self):
        if self.install and self.distribution.install_requires:
            self.distribution.fetch_build_eggs(
                self.distribution.install_requires)
        if self.test and self.distribution.tests_require:
            self.distribution.fetch_build_eggs(self.distribution.tests_require)
