#! /usr/bin/env python
#
# See README for usage instructions.

# pylint:disable=missing-module-docstring
# pylint:disable=g-bad-import-order
from distutils import util
import fnmatch
import glob
import os
import pkg_resources
import re
import subprocess
import sys
import sysconfig

# pylint:disable=g-importing-member
# pylint:disable=g-multiple-import

# We must use setuptools, not distutils, because we need to use the
# namespace_packages option for the "google" package.
from setuptools import setup, Extension, find_packages

from distutils.command.build_ext import build_ext as _build_ext
from distutils.command.build_py import build_py as _build_py
from distutils.command.clean import clean as _clean
from distutils.spawn import find_executable

# Find the Protocol Compiler.
if 'PROTOC' in os.environ and os.path.exists(os.environ['PROTOC']):
  protoc = os.environ['PROTOC']
elif os.path.exists('../src/protoc'):
  protoc = '../src/protoc'
elif os.path.exists('../src/protoc.exe'):
  protoc = '../src/protoc.exe'
elif os.path.exists('../vsprojects/Debug/protoc.exe'):
  protoc = '../vsprojects/Debug/protoc.exe'
elif os.path.exists('../vsprojects/Release/protoc.exe'):
  protoc = '../vsprojects/Release/protoc.exe'
else:
  protoc = find_executable('protoc')


def GetVersion():
  """Reads and returns the version from google/protobuf/__init__.py.

  Do not import google.protobuf.__init__ directly, because an installed
  protobuf library may be loaded instead.

  Returns:
      The version.
  """

  with open(os.path.join('google', 'protobuf', '__init__.py')) as version_file:
    exec(version_file.read(), globals())  # pylint:disable=exec-used
    return __version__  # pylint:disable=undefined-variable


def GenProto(source, require=True):
  """Generates a _pb2.py from the given .proto file.

  Does nothing if the output already exists and is newer than the input.

  Args:
      source: the .proto file path.
      require: if True, exit immediately when a path is not found.
  """

  if not require and not os.path.exists(source):
    return

  output = source.replace('.proto', '_pb2.py').replace('../src/', '')

  if (not os.path.exists(output) or
      (os.path.exists(source) and
       os.path.getmtime(source) > os.path.getmtime(output))):
    print('Generating %s...' % output)

    if not os.path.exists(source):
      sys.stderr.write("Can't find required file: %s\n" % source)
      sys.exit(-1)

    if protoc is None:
      sys.stderr.write(
          'protoc is not installed nor found in ../src.  Please compile it '
          'or install the binary package.\n')
      sys.exit(-1)

    protoc_command = [protoc, '-I../src', '-I.', '--python_out=.', source]
    if subprocess.call(protoc_command) != 0:
      sys.exit(-1)


def GenerateUnittestProtos():
  """Generates protobuf code for unittests."""
  GenProto('../src/google/protobuf/any_test.proto', False)
  GenProto('../src/google/protobuf/map_proto2_unittest.proto', False)
  GenProto('../src/google/protobuf/map_unittest.proto', False)
  GenProto('../src/google/protobuf/test_messages_proto3.proto', False)
  GenProto('../src/google/protobuf/test_messages_proto2.proto', False)
  GenProto('../src/google/protobuf/unittest_arena.proto', False)
  GenProto('../src/google/protobuf/unittest.proto', False)
  GenProto('../src/google/protobuf/unittest_custom_options.proto', False)
  GenProto('../src/google/protobuf/unittest_import.proto', False)
  GenProto('../src/google/protobuf/unittest_import_public.proto', False)
  GenProto('../src/google/protobuf/unittest_mset.proto', False)
  GenProto('../src/google/protobuf/unittest_mset_wire_format.proto', False)
  GenProto('../src/google/protobuf/unittest_no_generic_services.proto', False)
  GenProto('../src/google/protobuf/unittest_proto3_arena.proto', False)
  GenProto('../src/google/protobuf/util/json_format.proto', False)
  GenProto('../src/google/protobuf/util/json_format_proto3.proto', False)
  GenProto('google/protobuf/internal/any_test.proto', False)
  GenProto('google/protobuf/internal/descriptor_pool_test1.proto', False)
  GenProto('google/protobuf/internal/descriptor_pool_test2.proto', False)
  GenProto('google/protobuf/internal/factory_test1.proto', False)
  GenProto('google/protobuf/internal/factory_test2.proto', False)
  GenProto('google/protobuf/internal/file_options_test.proto', False)
  GenProto('google/protobuf/internal/import_test_package/import_public.proto',
           False)
  GenProto(
      'google/protobuf/internal/import_test_package/import_public_nested.proto',
      False)
  GenProto('google/protobuf/internal/import_test_package/inner.proto', False)
  GenProto('google/protobuf/internal/import_test_package/outer.proto', False)
  GenProto('google/protobuf/internal/missing_enum_values.proto', False)
  GenProto('google/protobuf/internal/message_set_extensions.proto', False)
  GenProto('google/protobuf/internal/more_extensions.proto', False)
  GenProto('google/protobuf/internal/more_extensions_dynamic.proto', False)
  GenProto('google/protobuf/internal/more_messages.proto', False)
  GenProto('google/protobuf/internal/no_package.proto', False)
  GenProto('google/protobuf/internal/packed_field_test.proto', False)
  GenProto('google/protobuf/internal/test_bad_identifiers.proto', False)
  GenProto('google/protobuf/internal/test_proto3_optional.proto', False)
  GenProto('google/protobuf/pyext/python.proto', False)


class CleanCmd(_clean):
  """Custom clean command for building the protobuf extension."""

  def run(self):
    # Delete generated files in the code tree.
    for (dirpath, unused_dirnames, filenames) in os.walk('.'):
      for filename in filenames:
        filepath = os.path.join(dirpath, filename)
        if (filepath.endswith('_pb2.py') or filepath.endswith('.pyc') or
            filepath.endswith('.so') or filepath.endswith('.o')):
          os.remove(filepath)
    # _clean is an old-style class, so super() doesn't work.
    _clean.run(self)


class BuildPyCmd(_build_py):
  """Custom build_py command for building the protobuf runtime."""

  def run(self):
    # Generate necessary .proto file if it doesn't exist.
    GenProto('../src/google/protobuf/descriptor.proto')
    GenProto('../src/google/protobuf/compiler/plugin.proto')
    GenProto('../src/google/protobuf/any.proto')
    GenProto('../src/google/protobuf/api.proto')
    GenProto('../src/google/protobuf/duration.proto')
    GenProto('../src/google/protobuf/empty.proto')
    GenProto('../src/google/protobuf/field_mask.proto')
    GenProto('../src/google/protobuf/source_context.proto')
    GenProto('../src/google/protobuf/struct.proto')
    GenProto('../src/google/protobuf/timestamp.proto')
    GenProto('../src/google/protobuf/type.proto')
    GenProto('../src/google/protobuf/wrappers.proto')
    GenerateUnittestProtos()

    # _build_py is an old-style class, so super() doesn't work.
    _build_py.run(self)

  def find_package_modules(self, package, package_dir):
    exclude = (
        '*test*',
        'google/protobuf/internal/*_pb2.py',
        'google/protobuf/internal/_parameterized.py',
        'google/protobuf/pyext/python_pb2.py',
    )
    modules = _build_py.find_package_modules(self, package, package_dir)
    return [(pkg, mod, fil) for (pkg, mod, fil) in modules
            if not any(fnmatch.fnmatchcase(fil, pat=pat) for pat in exclude)]


class BuildExtCmd(_build_ext):
  """Command class for building the protobuf Python extension."""

  def get_ext_filename(self, ext_name):
    # since python3.5, python extensions' shared libraries use a suffix that
    # corresponds to the value of sysconfig.get_config_var('EXT_SUFFIX') and
    # contains info about the architecture the library targets.  E.g. on x64
    # linux the suffix is ".cpython-XYZ-x86_64-linux-gnu.so" When
    # crosscompiling python wheels, we need to be able to override this
    # suffix so that the resulting file name matches the target architecture
    # and we end up with a well-formed wheel.
    filename = _build_ext.get_ext_filename(self, ext_name)
    orig_ext_suffix = sysconfig.get_config_var('EXT_SUFFIX')
    new_ext_suffix = os.getenv('PROTOCOL_BUFFERS_OVERRIDE_EXT_SUFFIX')
    if new_ext_suffix and filename.endswith(orig_ext_suffix):
      filename = filename[:-len(orig_ext_suffix)] + new_ext_suffix
    return filename


class TestConformanceCmd(_build_py):
  target = 'test_python'

  def run(self):
    # Python 2.6 dodges these extra failures.
    os.environ['CONFORMANCE_PYTHON_EXTRA_FAILURES'] = (
        '--failure_list failure_list_python-post26.txt')
    cmd = 'cd ../conformance && make %s' % (TestConformanceCmd.target,)
    subprocess.check_call(cmd, shell=True)


def GetOptionFromArgv(option_str):
  if option_str in sys.argv:
    sys.argv.remove(option_str)
    return True
  return False


def _GetFlagValues(flag_long, flag_short):
  """Searches sys.argv for distutils-style flags and yields values."""

  expect_value = flag_long.endswith('=')
  flag_res = [re.compile(r'--?%s(=(.*))?' %
                         (flag_long[:-1] if expect_value else flag_long))]
  if flag_short:
    flag_res.append(re.compile(r'-%s(.*)?' % (flag_short,)))

  flag_match = None
  for arg in sys.argv:
    # If the last arg was like '-O', check if this is the library we want.
    if flag_match is not None:
      yield arg
      flag_match = None
      continue

    for flag_re in flag_res:
      m = flag_re.match(arg)
      if m is None:
        continue
      if not expect_value:
        yield arg
        continue
      groups = m.groups()
      # Check for matches:
      #   --long-name=foo => ('=foo', 'foo')
      #   -Xfoo => ('foo')
      # N.B.: if the flag is like '--long-name=', then there is a value
      # (the empty string).
      if groups[0] or groups[-1]:
        yield groups[-1]
        continue
      flag_match = m

  return False


def HasStaticLibprotobufOpt():
  """Returns true if there is a --link-objects arg for libprotobuf."""

  lib_re = re.compile(r'(.*[/\\])?(lib)?protobuf([.]pic)?[.](a|lib)')
  for value in _GetFlagValues('link-objects=', 'O'):
    if lib_re.match(value):
      return True
  return False


def HasLibraryDirsOpt():
  """Returns true if there is a --library-dirs arg."""
  return any(_GetFlagValues('library-dirs=', 'L'))


if __name__ == '__main__':
  ext_module_list = []
  warnings_as_errors = '--warnings_as_errors'
  if GetOptionFromArgv('--cpp_implementation'):
    # Link libprotobuf.a and libprotobuf-lite.a statically with the
    # extension. Note that those libraries have to be compiled with
    # -fPIC for this to work.
    compile_static_ext = HasStaticLibprotobufOpt()
    if GetOptionFromArgv('--compile_static_extension'):
      # FUTURE: add a warning and deprecate --compile_static_extension.
      compile_static_ext = True
    extra_objects = None
    if compile_static_ext:
      libraries = None
      library_dirs = None
      if not HasStaticLibprotobufOpt():
        extra_objects = ['../src/.libs/libprotobuf.a',
                         '../src/.libs/libprotobuf-lite.a']
    else:
      libraries = ['protobuf']
      if HasLibraryDirsOpt():
        library_dirs = None
      else:
        library_dirs = ['../src/.libs']

    TestConformanceCmd.target = 'test_python_cpp'

    extra_compile_args = []

    message_extra_link_args = None
    api_implementation_link_args = None
    if 'darwin' in sys.platform:
      if sys.version_info[0] == 2:
        message_init_symbol = 'init_message'
        api_implementation_init_symbol = 'init_api_implementation'
      else:
        message_init_symbol = 'PyInit__message'
        api_implementation_init_symbol = 'PyInit__api_implementation'
      message_extra_link_args = [
          '-Wl,-exported_symbol,_%s' % message_init_symbol
      ]
      api_implementation_link_args = [
          '-Wl,-exported_symbol,_%s' % api_implementation_init_symbol
      ]

    if sys.platform != 'win32':
      extra_compile_args.append('-Wno-write-strings')
      extra_compile_args.append('-Wno-invalid-offsetof')
      extra_compile_args.append('-Wno-sign-compare')
      extra_compile_args.append('-Wno-unused-variable')
      extra_compile_args.append('-std=c++11')

    if sys.platform == 'darwin':
      extra_compile_args.append('-Wno-shorten-64-to-32')
      extra_compile_args.append('-Wno-deprecated-register')

    # https://developer.apple.com/documentation/xcode_release_notes/xcode_10_release_notes
    # C++ projects must now migrate to libc++ and are recommended to set a
    # deployment target of macOS 10.9 or later, or iOS 7 or later.
    if sys.platform == 'darwin':
      mac_target = str(sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET'))
      if mac_target and (pkg_resources.parse_version(mac_target) <
                         pkg_resources.parse_version('10.9.0')):
        os.environ['MACOSX_DEPLOYMENT_TARGET'] = '10.9'
        os.environ['_PYTHON_HOST_PLATFORM'] = re.sub(
            r'macosx-[0-9]+\.[0-9]+-(.+)', r'macosx-10.9-\1',
            util.get_platform())

    # https://github.com/Theano/Theano/issues/4926
    if sys.platform == 'win32':
      extra_compile_args.append('-D_hypot=hypot')

    # https://github.com/tpaviot/pythonocc-core/issues/48
    if sys.platform == 'win32' and  '64 bit' in sys.version:
      extra_compile_args.append('-DMS_WIN64')

    # MSVS default is dymanic
    if sys.platform == 'win32':
      extra_compile_args.append('/MT')

    if 'clang' in os.popen('$CC --version 2> /dev/null').read():
      extra_compile_args.append('-Wno-shorten-64-to-32')

    if warnings_as_errors in sys.argv:
      extra_compile_args.append('-Werror')
      sys.argv.remove(warnings_as_errors)

    # C++ implementation extension
    ext_module_list.extend([
        Extension(
            'google.protobuf.pyext._message',
            glob.glob('google/protobuf/pyext/*.cc'),
            include_dirs=['.', '../src'],
            libraries=libraries,
            extra_objects=extra_objects,
            extra_link_args=message_extra_link_args,
            library_dirs=library_dirs,
            extra_compile_args=extra_compile_args,
        ),
        Extension(
            'google.protobuf.internal._api_implementation',
            glob.glob('google/protobuf/internal/api_implementation.cc'),
            extra_compile_args=(extra_compile_args +
                                ['-DPYTHON_PROTO2_CPP_IMPL_V2']),
            extra_link_args=api_implementation_link_args,
        ),
    ])
    os.environ['PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION'] = 'cpp'

  # Keep this list of dependencies in sync with tox.ini.
  install_requires = []

  setup(
      name='protobuf',
      version=GetVersion(),
      description='Protocol Buffers',
      download_url='https://github.com/protocolbuffers/protobuf/releases',
      long_description="Protocol Buffers are Google's data interchange format",
      url='https://developers.google.com/protocol-buffers/',
      maintainer='protobuf@googlegroups.com',
      maintainer_email='protobuf@googlegroups.com',
      license='BSD-3-Clause',
      classifiers=[
          'Programming Language :: Python',
          'Programming Language :: Python :: 3',
          'Programming Language :: Python :: 3.7',
          'Programming Language :: Python :: 3.8',
          'Programming Language :: Python :: 3.9',
          'Programming Language :: Python :: 3.10',
      ],
      namespace_packages=['google'],
      packages=find_packages(
          exclude=[
              'import_test_package',
              'protobuf_distutils',
          ],),
      test_suite='google.protobuf.internal',
      cmdclass={
          'clean': CleanCmd,
          'build_py': BuildPyCmd,
          'build_ext': BuildExtCmd,
          'test_conformance': TestConformanceCmd,
      },
      install_requires=install_requires,
      ext_modules=ext_module_list,
      python_requires='>=3.7',
  )
