import re


def make_code_lusid_friendly(raw_code) -> str:
    """
    This function takes a column name and converts it to a LUSID friendly code creating LUSID objects. LUSID allows
    for up to 64 characters which can be lowercase and uppercase letters, numbers, a dash ("-") or an underscore ("_").
    The complete restrictions are here: https://support.lusid.com/what-is-a-code

    Parameters
    ----------
    raw_code : any
        A raw column header which needs special characters stripped out

    Returns
    -------
    friendly_code : str
        A LUSID friendly code with special characters removed
    """

    # Convert any type to a string
    try:
        raw_code = str(raw_code)
    except Exception as exception:
        raise ValueError(
            f"Could not convert value of {raw_code} with type {type(raw_code)} to a string. "
            + "Please convert to a format which can be cast to a string and try again"
        ) from exception

    # Check that it does not exceed the max length
    max_length = 64

    if len(raw_code) > max_length:
        raise ValueError(
            f"""The name {raw_code} is {len(raw_code)} characters long and exceeds the limit of {max_length}
                             for a code. Please shorten it by {len(raw_code) - 64} characters."""
        )

    # Specifically convert known unfriendly characters with a specific string and remove the rest completely
    friendly_code = re.sub(
        r"[^\w]",
        "",
        raw_code.replace("%", "Percentage")
        .replace("&", "and")
        .replace(".", "_")
        .replace("-", "_")
        .strip(),
    )

    return friendly_code