#!/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):
    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})
