import unicodedata
import re


def get_canonical_artist(artist):
    """
    Converts artist name string to canonical version, for comparison.

    This performs the following operations, in order:
        - lowercases the input string
        - replaces double hyphens with a space
        - strips diacritics and many other miscellaneous marks (like ``&``)
        - collapses multiple spaces in a row to a single space
        - strips leading "The"
        - drops featured artists from the end of the artist name by looking for:
            - ``ft``, ``feat``, or ``featuring``
            - optional period after the two abbreviations
            - optional parentheses around the whole thing
            - must have something following the "featuring" introduction, strips
              to the end of the artist name

    :param artist: String artist name
    :returns: Canonical artist name, suitable for comparison
    """

    def should_keep(c):
        return unicodedata.category(c)[0] in {"L", "N", "S", "Z"}

    return re.sub(
        r" (\()?(?:f(?:ea)?t\.?|featuring) .+(?(1)\))$",
        "",
        re.sub(
            r"^the ",
            "",
            re.sub(
                r"\s+",
                " ",
                "".join(
                    filter(
                        should_keep,
                        unicodedata.normalize(
                            "NFKD",
                            artist.lower().replace("--", " "),
                        ),
                    ),
                ),
            ),
        ),
    )