from typing import List
from typing import Dict
from typing import Tuple
from warnings import warn


def _construct_agg_info(aggregations: List[Dict]) -> Tuple[List[Dict], Dict, List]:
    """
    Helper function used to determine aggregation columns information and their
    respective settings.

    Examples
    --------

    >>> a = [
    ...     {"type": "union", "attribute_name": "variable_id"},
    ...     {
    ...         "type": "join_new",
    ...         "attribute_name": "member_id",
    ...         "options": {"coords": "minimal", "compat": "override"},
    ...     },
    ...     {
    ...         "type": "join_new",
    ...         "attribute_name": "dcpp_init_year",
    ...         "options": {"coords": "minimal", "compat": "override"},
    ...     },
    ... ]
    >>> aggregations, aggregation_dict, agg_columns = _construct_agg_info(a)
    >>> agg_columns
    ['variable_id', 'member_id', 'dcpp_init_year']
    >>> aggregation_dict
    {'variable_id': {'type': 'union'},
    'member_id': {'type': 'join_new',
    'options': {'coords': 'minimal', 'compat': 'override'}},
    'dcpp_init_year': {'type': 'join_new',
    'options': {'coords': 'minimal', 'compat': 'override'}}}
    """
    agg_columns = []
    aggregation_dict = {}
    if aggregations:
        # Sort aggregations to make sure join_existing is always done before join_new
        aggregations = sorted(aggregations, key=lambda i: i['type'], reverse=True)
        for agg in aggregations:
            key = agg['attribute_name']
            if agg['type'] == 'join_existing' and 'dim' not in agg['options']:
                message = f"""
            Missing `dim` option for `join_existing` operation across `{key}` attribute.
            For `join_existing` to properly work, `options` must contain the name of the existing dimension
            to use (for e.g.: something like {{'dim': 'time'}}).
                """
                warn(message)
            rest = agg.copy()
            del rest['attribute_name']
            aggregation_dict[key] = rest
        agg_columns = list(aggregation_dict.keys())
    return aggregations, aggregation_dict, agg_columns