package myth

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

	VarUserAuthorization    = `access_token`  // oauth token
	HTTPHeaderAuthorization = `Authorization` // HTTP header Authorization
	HTTPHeaderToken         = `X-Token`       // HTTP header Authorization 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,
	}
}

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

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

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

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

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