package errs

import (
	"context"

	"go.buf.build/protocolbuffers/go/linuxgit/tidbcloud/base"
	"go.uber.org/zap"

	"github.com/tidbcloud/tiinf/monitor/tilog"
)

var errMapper = map[int64]Error{
	ErrCodeBadRequest:             ErrBadRequest,
	ErrCodeUnauthorized:           ErrUnauthorized,
	ErrCodePaymentRequired:        ErrPaymentRequired,
	ErrCodeForbidden:              ErrForbidden,
	ErrCodeNotFound:               ErrNotFound,
	ErrCodeMethodNotAllowed:       ErrMethodNotAllowed,
	ErrCodeNotAcceptable:          ErrNotAcceptable,
	ErrCodeRequestTimeout:         ErrRequestTimeout,
	ErrCodeConflict:               ErrConflict,
	ErrCodeLengthRequired:         ErrLengthRequired,
	ErrCodePreconditionFailed:     ErrPreconditionFailed,
	ErrCodeRequestEntityTooLarge:  ErrRequestEntityTooLarge,
	ErrCodeRequestURITooLong:      ErrRequestURITooLong,
	ErrCodeUnsupportedMediaType:   ErrUnsupportedMediaType,
	ErrCodeExpectationFailed:      ErrExpectationFailed,
	ErrCodeTooManyRequests:        ErrTooManyRequests,
	ErrCodeInternalServerError:    ErrInternalServerError,
	ErrCodeNotImplemented:         ErrNotImplemented,
	ErrCodeBadGateway:             ErrBadGateway,
	ErrCodeServiceUnavailable:     ErrServiceUnavailable,
	ErrCodeRecordExist:            ErrRecordExist,
	ErrCodeIPBlocked:              ErrIPBlocked,
	ErrCodeUnderMaintenance:       ErrUnderMaintenance,
	ErrCodeDB:                     ErrInternalDB,
	ErrCodeRedis:                  ErrInternalRedis,
	ErrCodeMQ:                     ErrInternalMQ,
	ErrCodePanic:                  ErrInternalPanic,
	ErrCodeJsonMarshal:            ErrInternalJsonMarshal,
	ErrCodeTimeout:                ErrInternalTimeout,
	ErrCodeUnknown:                ErrInternalUnknown,
	ErrCodeHTTP:                   ErrInternalHTTP,
	ErrCodeGRPC:                   ErrInternalGRPC,
	ErrCodeSvcBilling:             ErrInternalSvcBilling,
	ErrCodeSvcInfraAPI:            ErrInternalSvcInfraAPI,
	ErrCodeSvcInfraMetering:       ErrInternalSvcInfraMetering,
	ErrCodeGeneralBusiness:        ErrInternalGeneralBusiness,
	ErrCodeOptimisticLockConflict: ErrInternalOptimisticLockConflict,
}

// ParseBaseResp restore tierr from code, but it will lose stack, and cause error
func ParseBaseResp(ctx context.Context, baseResp *base.BaseResp) error {
	if baseResp == nil {
		return nil
	}

	if baseResp.ErrCode == ErrCodeOK {
		return nil
	}

	errType, ok := errMapper[baseResp.ErrCode]
	if ok {
		return NewError(errType, baseResp.ErrMsg, nil)
	}

	tilog.Error(ctx, "un-handled grpc error occurred", zap.Any("baseResp", baseResp))
	return NewInternalGRPC("server error", nil)
}
