from pathlib import Path
from typing import Optional
from typing import List
import uuid


def make_metakernel(kernel_dir: Path, kernels: Optional[List[str]] = None) -> Path:
    """Create a uniquely-named SPICE metakernel in ``kernel_dir`` and return its path. If ``kernels`` is `None`, this
    function searches ``kernel_dir`` recursively and creates a metakernel containing all kernels found (except for
    other metakernels with file ending `.tm`). If ``kernels`` is given, this function creates a metakernel with all
    kernels contained in this input, whether they exist or not.

    :param kernel_dir: Main SPICE kernel directory, typically containing subdirectories for each kernel type
        (`fk`, `ck`, ...).
    :param kernels: List of kernels to include in the metakernel this function creates.
    :returns: Full path of the newly created metakernel file.
    """
    if not kernel_dir.exists():
        Path.mkdir(kernel_dir, parents=True)
    metakernel_file = kernel_dir / (uuid.uuid4().hex + ".tm")
    if kernels:
        list_kernels: List[Path] = [kernel_dir / k for k in kernels]
    else:
        list_kernels = list(kernel_dir.glob("*/*"))
    with open(metakernel_file, "w") as f:
        f.write("KPL/MK\n")
        f.write("\\begindata\n")
        f.write("PATH_VALUES=('" + str(kernel_dir) + "',)\n")
        f.write("PATH_SYMBOLS=('A',)\n")
        if list_kernels:
            f.write("KERNELS_TO_LOAD=(\n")
            for k in list_kernels:
                if ".tm" in str(k):
                    continue
                f.write("'$A/" + str(k.relative_to(kernel_dir)) + "',\n")
            f.write(")\n")
        f.write("\\begintext\n")
    return metakernel_file