import json


def _process_task_events(task_id, prev_events, tfr_client):
    """
    Process a globus task event list.

    This splits the events up into message events, which are events where the
    details field is a string, and json events, which is where the details
    field is a json object.

    Parameters
    ----------
    prev_events : `set`
        A set of already processed events.

    tfr_client : `globus_sdk.TransferClient`
        The transfer client to use to get the events.

    Returns
    -------
    prev_events : `set`
        The complete list of all event processed so far.

    json_events : `tuple` of `dict`
        All the events with json bodies.

    message_events : `tuple` of `dict`
        All the events with message bodies.
    """

    # Convert all the events into a (key, value) tuple pair
    events = set(map(lambda x: tuple(x.data.items()),
                     tfr_client.task_event_list(task_id, None)))
    # Drop all events we have seen before
    new_events = events.difference(prev_events)

    # Filter out the events which are json (start with {)
    json_events = set(filter(lambda x: dict(x).get("details", "").startswith("{"), new_events))
    # All the other events are message events
    message_events = tuple(map(dict, (new_events.difference(json_events))))

    def json_loader(x):
        """Modify the event so the json is a dict."""
        x['details'] = json.loads(x['details'])
        return x

    # If some of the events are json events, load the json.
    if json_events:
        json_events = tuple(map(dict, map(json_loader, map(dict, json_events))))
    else:
        json_events = tuple()

    return events, json_events, message_events