/*
 * Copyright 2020-2030 码匠君<herodotus@aliyun.com>
 *
 * Dante Engine licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Dante Engine 是 Dante Cloud 系统核心组件库，采用 APACHE LICENSE 2.0 开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1. 请不要删除和修改根目录下的LICENSE文件。
 * 2. 请不要删除和修改 Dante Engine 源码头部的版权声明。
 * 3. 请保留源码和相关描述文件的项目出处，作者声明等。
 * 4. 分发源码时候，请注明软件出处 <https://gitee.com/dromara/dante-cloud>
 * 5. 在修改包名，模块名称，项目代码等时，请注明软件出处 <https://gitee.com/dromara/dante-cloud>
 * 6. 若您的项目无法满足以上几点，可申请商业授权
 */

package org.dromara.dante.web.definition;

import cn.hutool.v7.core.tree.MapTree;
import cn.hutool.v7.core.tree.TreeNode;
import cn.hutool.v7.core.tree.TreeUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.dromara.dante.core.constant.SystemConstants;
import org.dromara.dante.core.domain.BaseDomain;
import org.dromara.dante.core.domain.Pagination;
import org.dromara.dante.core.domain.Result;
import org.springframework.core.convert.converter.Converter;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p> Description : Controller基础定义 </p>
 * <p>
 * 这里只在方法上做了泛型，主要是考虑到返回的结果数据可以是各种类型，而不一定受限于某一种类型。
 *
 * @author : gengwei.zheng
 * @date : 2024/1/30 1:06
 */
public interface Controller extends Pagination {

    /**
     * 数据实体转换为统一响应实体
     *
     * @param domain 数据实体
     * @param <D>    {@link BaseDomain} 子类型
     * @return {@link Result} Entity
     */
    default <D extends BaseDomain> Result<D> result(D domain) {
        if (ObjectUtils.isNotEmpty(domain)) {
            return Result.content(domain);
        } else {
            return Result.empty();
        }
    }

    /**
     * 数据列表转换为统一响应实体
     *
     * @param domains 数据实体 List
     * @param <D>     {@link BaseDomain} 子类型
     * @return {@link Result} List
     */
    default <D extends BaseDomain> Result<List<D>> result(List<D> domains) {

        if (null == domains) {
            return Result.failure("查询数据失败！");
        }

        if (CollectionUtils.isNotEmpty(domains)) {
            return Result.success("查询数据成功！", domains);
        } else {
            return Result.empty("未查询到数据！");
        }
    }

    /**
     * 数组转换为统一响应实体
     *
     * @param domains 数组
     * @param <T>     数组类型
     * @return {@link Result} List
     */
    default <T> Result<T[]> result(T[] domains) {

        if (null == domains) {
            return Result.failure("查询数据失败！");
        }

        if (ArrayUtils.isNotEmpty(domains)) {
            return Result.success("查询数据成功！", domains);
        } else {
            return Result.empty("未查询到数据！");
        }
    }

    /**
     * 数据 Map 转换为统一响应实体
     *
     * @param map 数据 Map
     * @return {@link Result} Map
     */
    default Result<Map<String, Object>> result(Map<String, Object> map) {

        if (null == map) {
            return Result.failure("查询数据失败！");
        }

        if (MapUtils.isNotEmpty(map)) {
            return Result.success("查询数据成功！", map);
        } else {
            return Result.empty("未查询到数据！");
        }
    }

    /**
     * 数据操作结果转换为统一响应实体
     *
     * @param parameter 数据ID
     * @return {@link Result} String
     */
    default Result<String> result(String parameter) {
        if (ObjectUtils.isNotEmpty(parameter)) {
            return Result.success("操作成功!", parameter);
        } else {
            return Result.failure("操作失败!", parameter);
        }
    }

    /**
     * 数据操作结果转换为统一响应实体
     *
     * @param status 操作状态
     * @return {@link Result} String
     */
    default Result<Boolean> result(boolean status) {
        if (status) {
            return Result.success("操作成功!", true);
        } else {
            return Result.failure("操作失败!", false);
        }
    }

    default <D extends BaseDomain> Result<List<MapTree<String>>> result(List<D> domains, Converter<D, TreeNode<String>> toTreeNode) {
        if (ObjectUtils.isNotEmpty(domains)) {
            List<TreeNode<String>> treeNodes = domains.stream().map(toTreeNode::convert).collect(Collectors.toList());
            return Result.success("查询数据成功", TreeUtil.build(treeNodes, SystemConstants.TREE_ROOT_ID));
        } else {
            return Result.empty("未查询到数据！");
        }
    }
}
