package com.bcxin.ferry.dtos.response.result;

import com.bcxin.ferry.common.emus.StatusCode;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;

import lombok.Getter;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * 通用返回响应对象 所有的restful返回均需要以这个对象为准
 */
@Getter
@JsonPropertyOrder({"code", "msg", "timestamp", "data"})
public class RespResult<V> extends AbstractRespResult {

    /**
     * 响应内容，可能为空，如果为空，那么该值会设置为空的MAP
     */
    @JsonInclude(JsonInclude.Include.NON_NULL)
    private V data;

    protected RespResult(V result) {
        super();
        if (result == null) {
            //查看V的类型，决定返回类型
            Type superClass = getClass().getGenericSuperclass();
            if (superClass == null) {
                this.data = (V)new HashMap();
            } else {
                if (superClass instanceof ParameterizedType) {
                    Type[] actualTypeArguments = ((ParameterizedType) superClass).getActualTypeArguments();
                    if (actualTypeArguments != null && actualTypeArguments.length > 0) {
                        Class<?> clazz = (Class<?>) actualTypeArguments[0];
                        if (List.class.isAssignableFrom(clazz)) {
                            this.data = (V) new ArrayList();
                        } else {
                            this.data = (V) new HashMap();
                        }
                    }
                }
            }
        } else {
            this.data = result;
        }
    }

    protected RespResult(StatusCode statusCode, String message) {
        super(statusCode, message);
    }

    protected RespResult(int code, String message) {
        super(code, message);
    }

    protected RespResult(int code, String message, V result) {
        super(code, message);
        this.data = result;
    }

    /**
     * 错误响应
     */
    public static final <T> RespResult<T> failure(StatusCode statusCode) {
        return new RespResult<>(statusCode, statusCode.getDefaultMessage());
    }

    /**
     * 错误响应
     */
    public static final <T> RespResult<T> failure(int statusCode, String message) {
        return new RespResult<>(statusCode, message);
    }
    public static final <T> RespResult<T> failure(int statusCode,String message, T result) {
        return new RespResult<>(statusCode, message, result);
    }

    /**
     * 默认成功返回响应
     */
    public static final <T> RespResult<T> successful() {
        return new RespResult<>(StatusCode.succeed, StatusCode.succeed.getDefaultMessage());
    }

    /**
     * 自定义返回值的成功返回响应
     */
    public static final <T> RespResult<T> successful(String message) {
        return new RespResult<>(StatusCode.succeed, message);
    }

    /**
     * 全构造
     */
    public static final <T> RespResult<T> create(int statusCode, String message, T result) {
        return new RespResult<>(statusCode, message, result);
    }

    /**
     * 自定义返回值的成功返回响应
     */
    public static final <T> RespResult<T> successful(T result) {
        return new RespResult<>(result);
    }
}
