from typing import Type
from enum import Enum
from typing import Tuple
from typing import List


def keys_descriptions_from_enum(
        enum: Type[Enum],
        sort_keys: bool = False,
        keys_to_lower: bool = False,
        keys_to_upper: bool = False,
        key_to_description: str = ": ",
        joiner: str = " // ") -> Tuple[List[str], str]:
    """
    From an Enum subclass, return (keys, descriptions_as_formatted_string).
    This is a convenience function used to provide command-line help for
    options involving a choice of enums from an Enum class.
    """
    assert not (keys_to_lower and keys_to_upper)
    keys = [e.name for e in enum]
    if keys_to_lower:
        keys = [k.lower() for k in keys]
    elif keys_to_upper:
        keys = [k.upper() for k in keys]
    if sort_keys:
        keys.sort()
    try:
        descriptions = [
            f"{k}{key_to_description}{enum[k].value}"
            for k in keys
        ]
    except KeyError:
        raise KeyError(
            "You are trying to do case-insensitive lookup with a "
            "case-sensitive Enum. Use a metaclass like "
            "cardinal_pythonlib.enumlike.CaseInsensitiveEnumMeta"
        )
    description_str = joiner.join(descriptions)
    return keys, description_str