# Copyright 2019 The RE2 Authors.  All Rights Reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

import os
import re
import setuptools
import setuptools.command.build_ext
import shutil

long_description = r"""A drop-in replacement for the re module.

It uses RE2 under the hood, of course, so various PCRE features
(e.g. backreferences, look-around assertions) are not supported.
See https://github.com/google/re2/wiki/Syntax for the canonical
reference, but known syntactic "gotchas" relative to Python are:

  * PCRE supports \Z and \z; RE2 supports \z; Python supports \z,
    but calls it \Z. You must rewrite \Z to \z in pattern strings.

Known differences between this module's API and the re module's API:

  * The error class does not provide any error information as attributes.
  * The Options class replaces the re module's flags with RE2's options as
    gettable/settable properties. Please see re2.h for their documentation.
  * The pattern string and the input string do not have to be the same type.
    Any str will be encoded to UTF-8.
  * The pattern string cannot be str if the options specify Latin-1 encoding.

Known issues with regard to building the C++ extension:

  * Building requires RE2 to be installed on your system.
    On Debian, for example, install the libre2-dev package.
  * Building requires pybind11 to be installed on your system OR venv.
    On Debian, for example, install the pybind11-dev package.
    For a venv, install the pybind11 package from PyPI.
  * Building on macOS is known to work, but has been known to fail.
    For example, the system Python may not know which compiler flags
    to set when building bindings for software installed by Homebrew;
    see https://docs.brew.sh/Homebrew-and-Python#brewed-python-modules.
  * Building on Windows has not been tested yet and will probably fail.
"""


class BuildExt(setuptools.command.build_ext.build_ext):

  def build_extension(self, ext):
    if 'GITHUB_ACTIONS' not in os.environ:
      return super().build_extension(ext)

    cmd = ['bazel', 'build']
    try:
      cpu = os.environ['BAZEL_CPU']
      cmd.append(f'--cpu={cpu}')
      cmd.append(f'--platforms=//python:{cpu}')
      if cpu == 'x64_x86_windows':
        # Register the local 32-bit C++ toolchain with highest priority.
        # (This is likely to break in some release of Bazel after 7.0.0,
        # but this special case can hopefully be entirely removed then.)
        cmd.append(f'--extra_toolchains=@local_config_cc//:cc-toolchain-{cpu}')
    except KeyError:
      pass
    try:
      ver = os.environ['MACOSX_DEPLOYMENT_TARGET']
      cmd.append(f'--macos_minimum_os={ver}')
    except KeyError:
      pass
    # Register the local Python toolchains with highest priority.
    cmd.append('--extra_toolchains=//python/toolchains:all')
    cmd += ['--compilation_mode=opt', '--', ':all']
    self.spawn(cmd)

    # This ensures that f'_re2.{importlib.machinery.EXTENSION_SUFFIXES[0]}'
    # is the filename in the destination directory, which is what's needed.
    shutil.copyfile('../bazel-bin/python/_re2.so',
                    self.get_ext_fullpath(ext.name))

    cmd = ['bazel', 'clean', '--expunge']
    self.spawn(cmd)


def options():
  bdist_wheel = {}
  try:
    bdist_wheel['plat_name'] = os.environ['PLAT_NAME']
  except KeyError:
    pass
  return {'bdist_wheel': bdist_wheel}


def include_dirs():
  try:
    import pybind11
    yield pybind11.get_include()
  except ModuleNotFoundError:
    pass


ext_module = setuptools.Extension(
    name='_re2',
    sources=['_re2.cc'],
    include_dirs=list(include_dirs()),
    libraries=['re2'],
    extra_compile_args=['-fvisibility=hidden'],
)

# We need `re2` to be a package, not a module, because it appears that
# modules can't have `.pyi` files, so munge the module into a package.
PACKAGE = 're2'
try:
  os.makedirs(PACKAGE)
  for filename in (
      're2.py',
      # TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
      # 're2.pyi',
      # '_re2.pyi',
  ):
    with open(filename, 'r') as file:
      contents = file.read()
    filename = re.sub(r'^re2(?=\.py)', '__init__', filename)
    contents = re.sub(r'^(?=import _)', 'from . ', contents, flags=re.MULTILINE)
    with open(f'{PACKAGE}/{filename}', 'x') as file:
      file.write(contents)
  # TODO(junyer): Populate as per https://github.com/google/re2/issues/496.
  # with open(f'{PACKAGE}/py.typed', 'x') as file:
  #   pass

  setuptools.setup(
      name='google-re2',
      version='1.1.20240701',
      description='RE2 Python bindings',
      long_description=long_description,
      long_description_content_type='text/plain',
      author='The RE2 Authors',
      author_email='re2-dev@googlegroups.com',
      url='https://github.com/google/re2',
      packages=[PACKAGE],
      ext_package=PACKAGE,
      ext_modules=[ext_module],
      classifiers=[
          'Development Status :: 5 - Production/Stable',
          'Intended Audience :: Developers',
          'License :: OSI Approved :: BSD License',
          'Programming Language :: C++',
          'Programming Language :: Python :: 3.8',
      ],
      options=options(),
      cmdclass={'build_ext': BuildExt},
      python_requires='~=3.8',
  )
except:
  raise
else:
  shutil.rmtree(PACKAGE)
