package util

const (
	// ErrOk OK
	ErrOk = 0
	// ErrNotFound 404 route not found
	ErrNotFound = 1001
	// ErrException 500
	ErrException = 1002
	// ErrBadRequest 400 route params error
	ErrBadRequest = 1003
	// ErrMethodNotAllowed 405
	ErrMethodNotAllowed = 1004
	// ErrParamsError 415
	ErrParamsError = 1005
	// ErrUnAuthorized 401
	ErrUnAuthorized = 1006
	// ErrDataNotFound 404
	ErrDataNotFound = 1007
	// ErrNotAllowed 405
	ErrNotAllowed = 1008
	// ErrDataExists 400
	ErrDataExists = 1009
	// ErrDataValidate 403
	ErrDataValidate = 1010

	// VarUserAuthorization oauth token
	VarUserAuthorization = `access_token`

	// HTTPHeaderAuthorization HTTP header Authorization
	HTTPHeaderAuthorization = `Authorization`
	// HTTPHeaderToken HTTP header Authorization X-Token
	HTTPHeaderToken = `X-Token`
)

var (
	statusMessage map[int]string
)

// ReplyData define API output data
type ReplyData struct {
	Status    int               `json:"status" xml:"status"`                     // Status code
	Message   string            `json:"message" xml:"message"`                   // Message description
	Errs      map[string]string `json:"errors,omitempty" xml:"errors,omitempty"` // Errs errors
	PageCount int               `json:"pageCount,omitempty"`
	Total     int               `json:"total,omitempty" xml:"total,omitempty"` // Total data total
	List      interface{}       `json:"rows,omitempty" xml:"rows,omitempty"`   // List data list
	Data      interface{}       `json:"data,omitempty" xml:"data,omitempty"`   // Data data attribute
}

func init() {
	statusMessage = make(map[int]string)
	statusMessage[ErrOk] = `ok`
	statusMessage[ErrNotFound] = `Not found`
	statusMessage[ErrException] = `Exception`
	statusMessage[ErrBadRequest] = `Routing parameter error`
	statusMessage[ErrMethodNotAllowed] = `Method not allowed`
	statusMessage[ErrParamsError] = `Parameter or format error`
	statusMessage[ErrUnAuthorized] = `Not sign in or session has expired`
	statusMessage[ErrDataNotFound] = `Data not found`
	statusMessage[ErrNotAllowed] = `No access`
	statusMessage[ErrDataExists] = `Data exists`
	statusMessage[ErrDataValidate] = `Data verification failed`
}

// NewReplyData creates and return ReplyData with status and message
func NewReplyData(status int) *ReplyData {
	var (
		text   string
		exists bool
	)
	if text, exists = statusMessage[status]; !exists {
		text = `incorrect data type`
	}
	return &ReplyData{
		Status:  status,
		Message: text,
	}
}

// OkReplyData creates and return ReplyData with ok
func OkReplyData() *ReplyData {
	message, _ := statusMessage[ErrOk]
	return &ReplyData{
		Status:  ErrOk,
		Message: message,
	}
}

// ErrReplyData creates and return ReplyData with error and message
func ErrReplyData(status int, message string) *ReplyData {
	text, _ := statusMessage[status]
	errs := map[string]string{
		"message": message,
	}
	return &ReplyData{
		Status:  status,
		Message: text,
		Errs:    errs,
	}
}

// ErrorsReplyData creates and return ReplyData with errors
func ErrorsReplyData(status int, errors map[string]string) *ReplyData {
	message, _ := statusMessage[status]
	return &ReplyData{
		Status:  status,
		Message: message,
		Errs:    errors,
	}
}

// RowsReplyData creates and return ReplyData with total and list
func RowsReplyData(total, pageCount int, rows interface{}) *ReplyData {
	message, _ := statusMessage[ErrOk]
	return &ReplyData{
		Status:    ErrOk,
		Message:   message,
		List:      rows,
		Total:     total,
		PageCount: pageCount,
	}
}

// RowReplyData creates and return ReplyData with attr row
func RowReplyData(row interface{}) *ReplyData {
	message, _ := statusMessage[ErrOk]
	return &ReplyData{
		Status:  ErrOk,
		Message: message,
		Data:    row,
	}
}