#!/usr/bin/env python3

# Setup script for PyPI; use CMakeFile.txt to build extension modules

import contextlib
import os
import re
import shutil
import string
import subprocess
import sys
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Dict, Iterator, List, Union

import setuptools.command.sdist

DIR = Path(__file__).parent.absolute()
VERSION_REGEX = re.compile(
    r"^\s*#\s*define\s+PYBIND11_VERSION_([A-Z]+)\s+(.*)$", re.MULTILINE
)
VERSION_FILE = Path("pybind11/_version.py")
COMMON_FILE = Path("include/pybind11/detail/common.h")


def build_expected_version_hex(matches: Dict[str, str]) -> str:
    patch_level_serial = matches["PATCH"]
    serial = None
    major = int(matches["MAJOR"])
    minor = int(matches["MINOR"])
    flds = patch_level_serial.split(".")
    if flds:
        patch = int(flds[0])
        if len(flds) == 1:
            level = "0"
            serial = 0
        elif len(flds) == 2:
            level_serial = flds[1]
            for level in ("a", "b", "c", "dev"):
                if level_serial.startswith(level):
                    serial = int(level_serial[len(level) :])
                    break
    if serial is None:
        msg = f'Invalid PYBIND11_VERSION_PATCH: "{patch_level_serial}"'
        raise RuntimeError(msg)
    version_hex_str = f"{major:02x}{minor:02x}{patch:02x}{level[:1]}{serial:x}"
    return f"0x{version_hex_str.upper()}"


# PYBIND11_GLOBAL_SDIST will build a different sdist, with the python-headers
# files, and the sys.prefix files (CMake and headers).

global_sdist = os.environ.get("PYBIND11_GLOBAL_SDIST", False)

setup_py = Path(
    "tools/setup_global.py.in" if global_sdist else "tools/setup_main.py.in"
)
extra_cmd = 'cmdclass["sdist"] = SDist\n'

to_src = (
    (Path("pyproject.toml"), Path("tools/pyproject.toml")),
    (Path("setup.py"), setup_py),
)


# Read the listed version
loc: Dict[str, str] = {}
code = compile(VERSION_FILE.read_text(encoding="utf-8"), "pybind11/_version.py", "exec")
exec(code, loc)
version = loc["__version__"]

# Verify that the version matches the one in C++
matches = dict(VERSION_REGEX.findall(COMMON_FILE.read_text(encoding="utf8")))
cpp_version = "{MAJOR}.{MINOR}.{PATCH}".format(**matches)
if version != cpp_version:
    msg = f"Python version {version} does not match C++ version {cpp_version}!"
    raise RuntimeError(msg)

version_hex = matches.get("HEX", "MISSING")
exp_version_hex = build_expected_version_hex(matches)
if version_hex != exp_version_hex:
    msg = f"PYBIND11_VERSION_HEX {version_hex} does not match expected value {exp_version_hex}!"
    raise RuntimeError(msg)


# TODO: use literals & overload (typing extensions or Python 3.8)
def get_and_replace(
    filename: Path, binary: bool = False, **opts: str
) -> Union[bytes, str]:
    if binary:
        contents = filename.read_bytes()
        return string.Template(contents.decode()).substitute(opts).encode()

    return string.Template(filename.read_text()).substitute(opts)


# Use our input files instead when making the SDist (and anything that depends
# on it, like a wheel)
class SDist(setuptools.command.sdist.sdist):  # type: ignore[misc]
    def make_release_tree(self, base_dir: str, files: List[str]) -> None:
        super().make_release_tree(base_dir, files)

        for to, src in to_src:
            txt = get_and_replace(src, binary=True, version=version, extra_cmd="")

            dest = Path(base_dir) / to

            # This is normally linked, so unlink before writing!
            dest.unlink()
            dest.write_bytes(txt)  # type: ignore[arg-type]


# Remove the CMake install directory when done
@contextlib.contextmanager
def remove_output(*sources: str) -> Iterator[None]:
    try:
        yield
    finally:
        for src in sources:
            shutil.rmtree(src)


with remove_output("pybind11/include", "pybind11/share"):
    # Generate the files if they are not present.
    with TemporaryDirectory() as tmpdir:
        cmd = ["cmake", "-S", ".", "-B", tmpdir] + [
            "-DCMAKE_INSTALL_PREFIX=pybind11",
            "-DBUILD_TESTING=OFF",
            "-DPYBIND11_NOPYTHON=ON",
            "-Dprefix_for_pc_file=${pcfiledir}/../../",
        ]
        if "CMAKE_ARGS" in os.environ:
            fcommand = [
                c
                for c in os.environ["CMAKE_ARGS"].split()
                if "DCMAKE_INSTALL_PREFIX" not in c
            ]
            cmd += fcommand
        subprocess.run(cmd, check=True, cwd=DIR, stdout=sys.stdout, stderr=sys.stderr)
        subprocess.run(
            ["cmake", "--install", tmpdir],
            check=True,
            cwd=DIR,
            stdout=sys.stdout,
            stderr=sys.stderr,
        )

    txt = get_and_replace(setup_py, version=version, extra_cmd=extra_cmd)
    code = compile(txt, setup_py, "exec")
    exec(code, {"SDist": SDist})
