# Authors: The MNE-Python contributors.
# License: BSD-3-Clause
# Copyright the MNE-Python contributors.


from ..utils import logger, verbose
from .constants import FIFF
from .tag import read_tag


def dir_tree_find(tree, kind):
    """Find nodes of the given kind from a directory tree structure.

    Parameters
    ----------
    tree : dict
        Directory tree.
    kind : int
        Kind to find.

    Returns
    -------
    nodes : list
        List of matching nodes.
    """
    nodes = []

    if isinstance(tree, list):
        for t in tree:
            nodes += dir_tree_find(t, kind)
    else:
        #   Am I desirable myself?
        if tree["block"] == kind:
            nodes.append(tree)

        #   Search the subtrees
        for child in tree["children"]:
            nodes += dir_tree_find(child, kind)
    return nodes


@verbose
def make_dir_tree(fid, directory, start=0, indent=0, verbose=None):
    """Create the directory tree structure."""
    if directory[start].kind == FIFF.FIFF_BLOCK_START:
        tag = read_tag(fid, directory[start].pos)
        block = tag.data.item()
    else:
        block = 0

    logger.debug("    " * indent + f"start {{ {block}")

    this = start

    tree = dict()
    tree["block"] = block
    tree["id"] = None
    tree["parent_id"] = None
    tree["nent"] = 0
    tree["nchild"] = 0
    tree["directory"] = directory[this]
    tree["children"] = []

    while this < len(directory):
        if directory[this].kind == FIFF.FIFF_BLOCK_START:
            if this != start:
                child, this = make_dir_tree(fid, directory, this, indent + 1)
                tree["nchild"] += 1
                tree["children"].append(child)
        elif directory[this].kind == FIFF.FIFF_BLOCK_END:
            tag = read_tag(fid, directory[start].pos)
            if tag.data == block:
                break
        else:
            tree["nent"] += 1
            if tree["nent"] == 1:
                tree["directory"] = list()
            tree["directory"].append(directory[this])

            #  Add the id information if available
            if block == 0:
                if directory[this].kind == FIFF.FIFF_FILE_ID:
                    tag = read_tag(fid, directory[this].pos)
                    tree["id"] = tag.data
            else:
                if directory[this].kind == FIFF.FIFF_BLOCK_ID:
                    tag = read_tag(fid, directory[this].pos)
                    tree["id"] = tag.data
                elif directory[this].kind == FIFF.FIFF_PARENT_BLOCK_ID:
                    tag = read_tag(fid, directory[this].pos)
                    tree["parent_id"] = tag.data

        this += 1

    # Eliminate the empty directory
    if tree["nent"] == 0:
        tree["directory"] = None

    logger.debug(
        "    " * (indent + 1)
        + f"block = {tree['block']} nent = {tree['nent']} nchild = {tree['nchild']}"
    )
    logger.debug("    " * indent + f"end }} {block:d}")
    last = this
    return tree, last
