package e

import (
	"fmt"
	"path"
	"runtime"
)

type E struct {
	Code int    // 错误码
	msg  string // 报错代码
	st   string // 堆栈信息
}

func NewErrCode(code int) error {
	if msg, ok := MsgFlags[code]; ok {
		return E{code, msg, stack(3)}
	}
	return E{ERR_UNKNOWN, "unknown", stack(3)}
}

func NewErr(code int, msg string) error {
	return E{code, msg, stack(3)}
}

func NewErrf(code int, msg string, args ...interface{}) error {
	return E{code, fmt.Sprintf(msg, args), stack(3)}
}

func (e E) Error() string {
	return e.msg
}

func stack(skip int) string {
	stk := make([]uintptr, 32)
	str := ""
	l := runtime.Callers(skip, stk[:])
	for i := 0; i < l; i++ {
		f := runtime.FuncForPC(stk[i])
		name := f.Name()
		file, line := f.FileLine(stk[i])
		str += fmt.Sprintf("\n%-30s[%s:%d]", name, path.Base(file), line)
	}
	return str
}

// ErrorIsAccountBan is 检查这个账号是否被禁用的错误
func ErrorIsAccountBan(e error) bool {
	err, ok := e.(E)
	if ok && err.Code == 403029 {
		return true
	}
	return false
}

// ErrorIsAccountNoActive is 检查这个账号是否被禁用的错误
func ErrorIsAccountNoActive(e error) bool {
	err, ok := e.(E)
	if ok && err.Code == 403028 {
		return true
	}
	return false
}

// ErrorIsUserDel is 检查这个账号是否被删除
func ErrorIsUserDel(e error) bool {
	err, ok := e.(E)
	if ok && err.Code == 403053 {
		return true
	}
	return false
}
