import click
import json


def parse_colors(ctx, param, value):
    """Callback to parse color values from a JSON list or hexadecimal string
    to a RGB tuple.
    """
    colors = []
    for color in value:
        if isinstance(color, (list, tuple)):
            r, g, b = color
        elif color.startswith('#'):
            hex_color = color[1:]
            hex_color_len = len(hex_color)
            r, g, b = None, None, None
            try:
                if hex_color_len == 3:
                    r, g, b = [int(''.join([l] * 2), 16) for l in hex_color]
                elif hex_color_len == 6:
                    r, g, b = list(map(lambda x: int(''.join(x), 16),
                                       zip(*[iter(hex_color)] * 2)))
            except ValueError:
                raise click.BadParameter(
                    "Malformed hex color: {}".format(color))
        else:
            try:
                r, g, b = json.loads(color)
            except ValueError:
                raise click.BadParameter(
                    "Malformed JSON or hexadecimal string: {}".format(color))
        if all(isinstance(c, int) and 0 <= c <= 255 for c in (r, g, b)):
            colors.append((r, g, b))
        else:
            raise click.BadParameter(
                "Invalid color value: {}".format(color))
    return colors