package protocol

import (
	"encoding/json"
)

//CustomErrParse 解析自定义错误结构体
type CustomErrParse interface {
	ParseToMessage() *ResponseMessage
}

//ErrorMap 统一消息错误编码
type ErrorMap map[int]string

//Search 搜索错误描述
func (m ErrorMap) Search(code int) ErrorCode {
	if v, ok := m[code]; ok {
		return ErrorCode{
			Errno:  code,
			Errmsg: v,
		}
	}
	return ErrorCode{}
}

//ErrorCode 统一错误结构
type ErrorCode struct {
	Errno  int    `json:"code"`
	Errmsg string `json:"msg"`
}

//ResponseMessage 统一返回消息结构体
type ResponseMessage struct {
	ErrorCode
	Data interface{} `json:"data"`
}

func NewMesage(code int) *ResponseMessage {
	return &ResponseMessage{
		ErrorCode: SearchErr(code),
		Data:      nil,
	}
}

//ErrWithMessage  自定义错误结构
type ErrWithMessage struct {
	Err error `json:"-"`
	ErrorCode
}

var (
	_ CustomErrParse = new(ErrWithMessage)
	_ error          = new(ErrWithMessage)
)

//NewErrWithMessage 构建错误返回
//code:用于匹配统一消息错误编码 eRR:填充嵌套错误
func NewErrWithMessage(code int, eRR ...error) *ErrWithMessage {
	r := &ErrWithMessage{
		ErrorCode: SearchErr(code),
	}
	if len(eRR) > 0 {
		r.Err = eRR[0]
	}
	return r
}

//Error 实现接口error 中的方法
//将ErrorCode转为json数据,建议用于日志记录
func (e ErrWithMessage) Error() string {
	bt, _ := json.Marshal(e.ErrorCode)
	return string(bt)
}

//Unwrap 接口实现
func (e ErrWithMessage) Unwrap() error {
	return e.Err
}

//ParseToMessage 实现CustomErrParse的接口
func (e ErrWithMessage) ParseToMessage() *ResponseMessage {
	return &ResponseMessage{
		ErrorCode: e.ErrorCode,
		Data:      nil,
	}
}