""" Based on numpy's approach to exposing compiler features via a config header.
Unfortunately that file is not exposed, so re-implement the portions we need.
"""
import os
import sys
import textwrap
from distutils.command.config import config as Config
from typing import List

OPTIONAL_FUNCTION_ATTRIBUTES = [
    ("HAVE_ATTRIBUTE_OPTIMIZE_OPT_3", '__attribute__((optimize("O3")))')
]

OPTIONAL_HEADERS = [("HAVE_SSE2", "emmintrin.h")]

OPTIONAL_INTRINSICS = [
    ("HAVE___BUILTIN_ISNAN", "__builtin_isnan", "0."),
    ("HAVE_ISNAN", "isnan", "0."),
    ("HAVE__ISNAN", "_isnan", "0."),
]


def get_python_header_include() -> List[str]:
    if sys.platform == "win32":
        suffix = ["include"]
    else:
        suffix = ["include", "python" + sys.version[:3] + sys.abiflags]

    results = []
    for prefix in [sys.prefix, sys.exec_prefix]:
        results.append(os.path.join(prefix, *suffix))

    return results


def _get_compiler_list(cmd: Config) -> str:
    """Return the compiler command as a list of strings. Distutils provides a
    wildly inconsistent API here:
      - UnixCCompiler returns a list
      - MSVCCompiler intentionally doesn't set this variable
      - CygwinCompiler returns a string

    As we are focused on identifying gcc vs clang right now, we ignore MSVC's
    bad result and convert all results into lists of strings
    """
    compiler = getattr(cmd.compiler, "compiler", "")
    if isinstance(compiler, str):
        compiler = compiler.split()
    return compiler


def is_gcc(cmd: Config) -> bool:
    return any("gcc" in x for x in _get_compiler_list(cmd))


def is_clang(cmd: Config) -> bool:
    return any("clang" in x for x in _get_compiler_list(cmd))


def check_inline(cmd: Config) -> str:
    """Return the inline identifier (may be empty)."""