package secondaryconfirm

import (
	"fmt"
	"net/http"
)

type ErrCodeType string

const (
	// EFeatureNotEnabled represents some used feature is not enabled
	EFeatureNotEnabled ErrCodeType = "FeatureNotEnabled"
	// EResourceStatusConflict represents resource status conflict, please refresh and try it again
	EResourceStatusConflict ErrCodeType = "ResourceStatusConflict"
	// EClusterUnderConfigChanging represents the cluster is under config changing, and can't apply another config changing
	EClusterUnderConfigChanging ErrCodeType = "ClusterUnderConfigChanging"
)

type ErrorInfo struct {
	Code    int         `json:"code"` // same as http code
	ErrCode ErrCodeType `json:"errcode"`
	Message string      `json:"message"`
}

func NewErrorInfo(statusCode int, message string) ErrorInfo {
	return ErrorInfo{Code: statusCode, Message: message}
}

func (err ErrorInfo) Error() string {
	return fmt.Sprintf("code: %d, message: %s", err.Code, err.Message)
}

func (err ErrorInfo) StatusCode() int {
	return err.Code
}

func (err ErrorInfo) WithErrCode(code ErrCodeType) ErrorInfo {
	err.ErrCode = code
	return err
}

var (
	ErrInvalidParameter           = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusBadRequest, msg) }
	ErrInternal                   = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusInternalServerError, msg) }
	ErrUnauthorized               = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusBadRequest, msg) }
	ErrForbidden                  = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusBadRequest, msg) }
	ErrNotSatisfied               = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusPreconditionRequired, msg) }
	ErrNotFound                   = func(msg string) ErrorInfo { return NewErrorInfo(http.StatusBadRequest, msg) }
	ErrTooManyRequest             = func() ErrorInfo { return NewErrorInfo(http.StatusTooManyRequests, "Too many request.") }
	ErrStatusConflict             = NewErrorInfo(http.StatusBadRequest, "resource status conflict").WithErrCode(EResourceStatusConflict)
	ErrFeatureNotEnabled          = NewErrorInfo(http.StatusBadRequest, "This feature is not enabled for this cluster, please contact the devops team to enable it").WithErrCode(EFeatureNotEnabled)
	ErrClusterUnderConfigChanging = NewErrorInfo(http.StatusBadRequest, "The cluster is under config changing, please refresh page and try it again").WithErrCode(EClusterUnderConfigChanging)
	ErrClusterConfigApplyDisabled = func(msg string) ErrorInfo {
		return NewErrorInfo(http.StatusBadRequest, fmt.Sprintf("The cluster is disabled for applying config, please contact the TiDB Cluster Service team. reason: %s", msg))
	}
)
