# icsdll/setup.py

"""Icsdll package setuptools script."""

import glob
import os
import re
import sys

from setuptools import setup
from setuptools._distutils import ccompiler

try:
    from wheel.bdist_wheel import bdist_wheel as _bdist_wheel

    class bdist_wheel(_bdist_wheel):  # type: ignore[no-redef]
        """Override wheel tag to py3-none-win_amd64."""

        def get_tag(self) -> tuple[str, str, str]:
            return 'py3', 'none', 'win_amd64'

    cmdclass: dict[str, object] = {'bdist_wheel': bdist_wheel}
except ImportError:
    cmdclass = {}

ONEAPI_ROOT = os.environ.get('ONEAPI_ROOT', r'C:\PROGRA~2\Intel\oneAPI')


def search(pattern: str, string: str, flags: int = 0) -> str:
    """Return first match of pattern in string."""
    match = re.search(pattern, string, flags)
    if match is None:
        raise ValueError(f'{pattern!r} not found')
    return match.groups()[0]


def fix_docstring_examples(docstring: str) -> str:
    """Return docstring with examples fixed for GitHub."""
    start = True
    indent = False
    lines = ['..', '  This file is generated by setup.py', '']
    for line in docstring.splitlines():
        if not line.strip():
            start = True
            indent = False
        if line.startswith('>>> '):
            indent = True
            if start:
                lines.extend(['.. code-block:: python', ''])
                start = False
        lines.append(('    ' if indent else '') + line)
    return '\n'.join(lines)


with open('icsdll/icsdll.py', encoding='utf-8') as fh:
    code = fh.read()

version = search(r"__version__ = '(.*?)'", code).replace('.x.x', '.dev0')

description = search(r'"""(.*)\.(?:\r\n|\r|\n)', code)

readme = search(
    r'(?:\r\n|\r|\n){2}"""(.*)"""(?:\r\n|\r|\n){2}from __future__',
    code,
    re.MULTILINE | re.DOTALL,
)
readme = '\n'.join(
    [description, '=' * len(description), *readme.splitlines()[1:]]
)


kwargs: dict[str, object] = {}

if 'sdist' in sys.argv:
    # update LICENSE and README files

    with open('README.rst', 'w', encoding='utf-8') as fh:
        fh.write(fix_docstring_examples(readme))

    license = search(
        r'(# Copyright.*?(?:\r\n|\r|\n))(?:\r\n|\r|\n)+""',
        code,
        re.MULTILINE | re.DOTALL,
    )
    license = license.replace('# ', '').replace('#', '')

    with open('LICENSE', 'w', encoding='utf-8') as fh:
        fh.write('BSD-3-Clause license\n\n')
        fh.write(license)

elif (
    sys.platform == 'win32'
    and '64 bit' in sys.version
    and sys.version_info[:2] >= (3, 11)
):
    # build DLL for 64-bit Windows
    for f in glob.glob(os.path.join('icsdll', 'ICSx64.*')):
        try:
            os.remove(f)
        except Exception:  # noqa: S110
            pass

    sources = [
        os.path.join('ics', c)
        for c in ('dllmain.cpp', 'ics.cpp', 'rfft.cpp', 'yxt.cpp', 'nlsp.cpp')
    ]

    compiler = ccompiler.new_compiler()
    objects = compiler.compile(
        sources,
        'build',
        extra_preargs=[
            '/EHsc',
            '/FD',
            '/DICS_EXPORTS',
            '/DICS_SIMFCS',
            '/openmp',
        ],
        include_dirs=['ics', ONEAPI_ROOT + '/mkl/latest/include'],
    )

    compiler.link_shared_lib(
        objects,
        os.path.join('icsdll', 'ICSx64'),
        extra_preargs=['/DLL'],
        libraries=[
            'mkl_core',
            'mkl_intel_lp64',
            'mkl_sequential',
            # 'mkl_intel_thread',
            # 'libiomp5md',
        ],
        library_dirs=[ONEAPI_ROOT + '/mkl/latest/lib'],
    )
    kwargs = {
        'package_data': {'icsdll': ['ICSx64.dll', '*.dll']},
        'libraries': [('', {'sources': []})],  # sets ispurelib = False
    }
else:
    kwargs = {}


setup(
    name='icsdll',
    cmdclass=cmdclass,
    version=version,
    description=description,
    long_description=readme,
    long_description_content_type='text/x-rst',
    author='Christoph Gohlke',
    author_email='cgohlke@cgohlke.com',
    url='https://www.cgohlke.com',
    project_urls={
        'Bug Tracker': 'https://github.com/cgohlke/icsdll/issues',
        'Source Code': 'https://github.com/cgohlke/icsdll',
        # 'Documentation': 'https://',
    },
    python_requires='>=3.11',
    install_requires=['numpy'],
    packages=['icsdll'],
    license='BSD-3-Clause',
    zip_safe=False,
    platforms=['Windows'],
    classifiers=[
        'Development Status :: 3 - Alpha',
        'Intended Audience :: Science/Research',
        'Intended Audience :: Developers',
        'Operating System :: Microsoft :: Windows',
        'Programming Language :: C++',
        'Programming Language :: Python :: 3 :: Only',
        'Programming Language :: Python :: 3.11',
        'Programming Language :: Python :: 3.12',
        'Programming Language :: Python :: 3.13',
        'Programming Language :: Python :: 3.14',
    ],
    **kwargs,
)
