from datetime import datetime
from enum import Enum
from uuid import UUID
from flask import request

# This is somewhat :(
#
# So we've already batched the database fetches for a bunch of sqlalchemy
# objects together. These objects probably have joins/joinedloads, though,
# which may also need to do data fetches (and/or have joins themselves that
# have data fetches.) Without the function you're reading about now, those
# would all happen serially.
#
# So here's what we'll do. We'll write a function that operates on a list of
# already-converted dictionaries (from a Crumbler.) We can
# find every key/value pair within that dict that has its own data fetching to
# do [1], batch all of that data fetching together and crumble those objects.
# Now we can recursively run ourselves on that resulting list, and replace
# the original value with the final result from this greedy fetch.
#
# Another way of describing this is that we do a depth first search and crumble
# everything we come across, transforming the original structure in place.
#
# [1] The implmentation does this for every value that has its own Crumble object
# even if get_extra_attrs_from_db is a no-op
#
# Based on the way serialization is written, this cannot change what we'd
# output... we're basically allowed to run object_to_dict on objects whenever
# we want, as long as we make sure to run serialize on them afterwards. In this
# case, the caller of this function will run serialize on this entire tree
# after we're done.
#
# Philosophically, this function is written so that running it can only make
# things better: there may be corner cases where it fails to batch something
# that should be batched, but if it fails that won't break anything
#
# @param (data): a list of objects that have already had serializer run on them
#
# NOTE: right now, this function doesn't fully work


def greedily_try_to_batch_data_fetches(data, extended_registry):
    # we only care about lists of dicts
    if not isinstance(data, list) or not isinstance(data[0], dict):
        return data

    for k in data[0].keys():
        if isinstance(data[0][k], _PASSTHROUGH):
            # cheap check to see if value is boring before calling
            # get_crumbler
            continue

        crumbler = get_crumbler(data[0][k], extended_registry)