from typing import ByteString
from typing import Tuple


def decode_apdu_command(buf: ByteString) -> Tuple[int, int, int, int, bytes, int, bool]:
    """
    Reverse of encode_apdu_command to parse an encoded command.

    Args:
        buf: An encoded APDU command

    Returns:
        cla, ins, p1, p2, data, expected_length, extended

    Raises:
        ValueError: bad encoding.
    """

    cla, ins, p1, p2 = buf[:4]
    rem = len(buf) - 4

    # Parse short fields

    if rem == 0:
        return cla, ins, p1, p2, b"", 0, False

    if rem == 1:
        return cla, ins, p1, p2, b"", buf[4] or 256, False

    if buf[4] != 0:
        if rem - 1 == buf[4]:
            return cla, ins, p1, p2, bytes(buf[5:]), 0, False

        if rem - 1 == buf[4] + 1:
            return cla, ins, p1, p2, bytes(buf[5:-1]), buf[-1] or 256, False

        raise ValueError

    if rem == 2:
        raise ValueError

    # Parse extended fields

    tmp = (buf[5] << 8) | buf[6]
    if rem == 3:
        return cla, ins, p1, p2, b"", tmp or 65536, True

    if rem - 3 == tmp:
        return cla, ins, p1, p2, bytes(buf[7:]), 0, True

    if rem - 3 == tmp + 2:
        return cla, ins, p1, p2, bytes(buf[7:-2]), ((buf[-2] << 8) | buf[-1]) or 65536, True

    raise ValueError