from functools import reduce
import os
import glob
import datetime as dt


def read_info_file(file_name):
    """
    Reads the info file and returns the stored metadata in a dictionary. The dictionary may be nested.
    @param file_name:  The name of the info file.
    @return: dictionary, the stored information.
    """
    root = {}
    with open(file_name, 'r') as f:
        lines = f.readlines()
        for l in lines:
            if not l.startswith("#"):
                continue
            l = l.strip("#").strip()
            if len(l) == 0:
                continue
            if not ": " in l:  # subsection
                sec = {}
                root[l[:-1] if l.endswith(":") else l] = sec
            else:
                parts = l.split(': ')
                sec[parts[0].strip()] = parts[1].strip('"').strip()
    return root


def find_key_recursive(dictionary, key, path=[]):
    assert(isinstance(dictionary, dict))
    if key in dictionary.keys():
        path.append(key)
        return True
    for k in dictionary.keys():
        if isinstance(dictionary[k], dict):
            if find_key_recursive(dictionary[k], key, path):
                path.insert(-1, k)
                break
    return len(path) > 0


def deep_get(dictionary, keys, default=None):
    assert(isinstance(dictionary, dict))
    assert(isinstance(keys, list))
    return reduce(lambda d, key: d.get(key, default) if isinstance(d, dict) else default, keys, dictionary)


def read_dataset_info(info_file):
    exp = ""
    quality = ""
    comment = ""
    rec_date = None
    has_nix = False
    if not os.path.exists(info_file):
        return exp, rec_date, quality, comment, has_nix
    has_nix = len(glob.glob(os.path.sep.join(info_file.split(os.path.sep)[:-1]) + os.path.sep + "*.nix")) > 0
    info = read_info_file(info_file)
    p = []
    find_key_recursive(info, "Experimenter", p)
    if len(p) > 0:
        exp = deep_get(info, p)
    p = []
    find_key_recursive(info, "Date", p)
    if len(p) > 0:
        rec_date = dt.date.fromisoformat(deep_get(info, p))
    p = []
    find_key_recursive(info, "Recording quality", p)
    if len(p) > 0:
        quality = deep_get(info, p)
    find_key_recursive(info, "Comment", p)
    if len(p) > 0:
        comment = deep_get(info, p, default="")

    return exp, rec_date, quality, comment, has_nix