# ^^^^^^^^^^^^^^^^^^^^^^^^
# ====> Main Logging <====
# ^^^^^^^^^^^^^^^^^^^^^^^^
init_log_file(nt::NamedTuple, args...) = init_log_file(values(nt), args...);
function init_log_file(t::Tuple, location::String = default_log_location, name::String = "", init_policy = tb_overwrite)
    logger = nothing;

    log_name = log_appendix(t);
    log_name = name * log_name;

    logger, log_name = search_init_fn(t, location, log_name, init_policy);

    return logger, log_name;

end



log_appendix(nt::NamedTuple) = log_appendix(values(nt));
function log_appendix(t::Tuple)
    log_name = "";

    for elem in t
        tp = typeof(elem);
        appendix_ms = methods(log_appendix, [tp], [Ses]);
        if !isempty(appendix_ms)
            log_name *= log_appendix(elem);
        end
    end

    return log_name;

end



search_init_fn(nt::NamedTuple, args...) = search_init_fn(values(nt));
function search_init_fn(t::Tuple, location::String = default_log_location, name::String = "", init_policy = tb_overwrite)
    logger = nothing;
    log_name = "";

    for elem in t
        tp = typeof(elem);
        logging_ms = methods(init_log_file, [tp], [Ses]);
        if !isempty(logging_ms)
            logger, log_name = init_log_file(elem, location, name, init_policy);
        end
        searching_ms = methods(search_init_fn, [tp], [Ses]);
        if !isempty(searching_ms)
            logger, log_name = search_init_fn(elem, location, name, init_policy);
        end
    end

    return logger, log_name;

end




logging(nt::NamedTuple, args...) = logging(values(nt), args...);
function logging(t::Tuple, logger = TBLogger(default_log_location, tb_overwrite), group = "", appendix = "")
    for elem in t
        tp = typeof(elem);
        logging_ms = methods(logging, [tp], [Ses]);
        if !isempty(logging_ms)
            logging(elem, logger, group, appendix);
        end
    end
end



# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# ====> Basic layers Logging <====
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@forward Chain.layers init_log_file
@forward Recur.cell init_log_file
@forward SkipConnection.layers init_log_file

@forward Chain.layers log_appendix
@forward Recur.cell log_appendix
@forward SkipConnection.layers log_appendix

@forward Chain.layers logging
@forward Recur.cell logging
@forward SkipConnection.layers logging



# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
# ====> 'SESmap' Logging <====
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@forward SesMap.operator init_log_file
@forward SesMap.operator log_appendix
@forward SesMap.operator logging