# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

import os
import sys

from pathlib import Path
from setuptools import setup, Extension
try:
    import tomllib as toml
except ImportError:
    import tomli as toml

# ========================== General purpose vals to describe our current platform ==========================
is_windows = sys.platform.startswith('win32')
is_macos = sys.platform.startswith('darwin')
is_pypy = "PyPy" in sys.version
is_supported_platform = sys.platform != "cli" and not sys.platform.startswith("java")
is_supported_arch = sys.byteorder != "big"
is_supported = is_supported_platform and is_supported_arch

# ========================== A few upfront checks ==========================
platform_unsupported_msg = \
"""
===============================================================================
The optional C extensions are not supported on this platform.
===============================================================================
"""

arch_unsupported_msg = \
"""
===============================================================================
The optional C extensions are not supported on big-endian systems.
===============================================================================
"""

pypy_unsupported_msg = \
"""
=================================================================================
Some optional C extensions are not supported in PyPy. Only murmur3 will be built.
=================================================================================
"""

if is_pypy:
    sys.stderr.write(pypy_unsupported_msg)
if not is_supported_platform:
    sys.stderr.write(platform_unsupported_msg)
elif not is_supported_arch:
    sys.stderr.write(arch_unsupported_msg)

# ========================== Extensions ==========================
pyproject_toml = Path(__file__).parent / "pyproject.toml"
with open(pyproject_toml,"rb") as f:
    pyproject_data = toml.load(f)
driver_project_data = pyproject_data["tool"]["cassandra-driver"]

def key_or_false(k):
    return driver_project_data[k] if k in driver_project_data else False

try_murmur3 = key_or_false("build-murmur3-extension") and is_supported
try_libev = key_or_false("build-libev-extension") and is_supported
try_cython = key_or_false("build-cython-extensions") and is_supported and not is_pypy

build_concurrency = driver_project_data["build-concurrency"]

exts = []
if try_murmur3:
    murmur3_ext = Extension('cassandra.cmurmur3', sources=['cassandra/cmurmur3.c'])
    sys.stderr.write("Appending murmur extension %s\n" % murmur3_ext)
    exts.append(murmur3_ext)

if try_libev:
    libev_includes = driver_project_data["libev-includes"]
    libev_libs = driver_project_data["libev-libs"]
    if is_macos:
        libev_includes.extend(['/opt/homebrew/include', os.path.expanduser('~/homebrew/include')])
        libev_libs.extend(['/opt/homebrew/lib'])
    libev_ext = Extension('cassandra.io.libevwrapper',
                          sources=['cassandra/io/libevwrapper.c'],
                          include_dirs=libev_includes,
                          libraries=['ev'],
                          library_dirs=libev_libs)
    sys.stderr.write("Appending libev extension %s\n" % libev_ext)
    exts.append(libev_ext)

if try_cython:
    sys.stderr.write("Trying Cython builds in order to append Cython extensions\n")
    try:
        from Cython.Build import cythonize
        cython_candidates = ['cluster', 'concurrent', 'connection', 'cqltypes', 'metadata',
                             'pool', 'protocol', 'query', 'util']
        compile_args = [] if is_windows else ['-Wno-unused-function']
        exts.extend(cythonize(
            [Extension('cassandra.%s' % m, ['cassandra/%s.py' % m],
                       extra_compile_args=compile_args)
                       for m in cython_candidates],
                       nthreads=build_concurrency,
                       exclude_failures=True))

        exts.extend(cythonize(
            Extension("*", ["cassandra/*.pyx"],
                      extra_compile_args=compile_args),
                      nthreads=build_concurrency))
    except Exception as exc:
        sys.stderr.write("Failed to cythonize one or more modules. These will not be compiled as extensions (optional).\n")
        sys.stderr.write("Cython error: %s\n" % exc)

# ========================== And finally setup() itself ==========================
setup(
    ext_modules = exts
)