package com.ema.common.utils;


import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * 树形节点标识，同时定义树形结果中节点的基本行为。
 * <p>
 * 请注意，树形结果的实现类必须实现该接口，同时需要添加{@link Comparable#compareTo(T)}方法，用于排序<p/>
 * 根据自己的实际业务需求，自行删除或实现排序方法
 *
 * @param <T> 节点类型，实现该接口的实现类
 * @param <ID> 节点ID类型
 * @author KVSonen
 */
public interface TreeNode<T, ID> extends Comparable<T> {

    /**
     * 获取当前节点的ID，此ID值一般推荐使用数据库中的ID。<p/>
     * 这里的ID值为了通用性，定义为泛型，根据实际业务需求注入自己的ID类型。
     *
     * @return 当前节点的ID值
     */
    ID getId();

    /**
     * 获取当前节点的父节点ID。
     *
     * @return 父节点的ID值。
     */
    ID getParentId();

    /**
     * 获取当前节点的子节点集合，节点和子节点根据id和parentId进行关联
     *
     * @return 当前节点的子节点集合
     * @see TreeNode#getId()
     * @see TreeNode#getParentId()
     */
    List<T> getChildren();

    /**
     * 向当前节点添加一个子节点，此处添加按照逐一添加的方式。根据实际业务需要，实现类可以拥有自己setChildren()方法。<p/>
     * 但还是推荐实现类都实现该方法，因为在 TreeUtil 中构建树形结构
     * 时，是通过该方法进行子节点的构建。
     *
     * @param child 需要添加的子节点
     */
    void addChild(T child);

    /**
     * 设置当前节点是否选中。
     *
     */
    void setChecked(boolean checked);

    /**
     * 判断当前节点是否拥有子节点。该方法主要用于前端展示的判断依据。
     *
     * @return 是否拥有子节点，如果当前节点拥有子节点，则返回true，否则返回false。
     */
    @SuppressWarnings("unused")
    default boolean hasChild() {
        return !CollectionUtils.isEmpty(getChildren());
    }
}


