package auditloghandler

import (
	"context"
	"fmt"

	"github.com/gin-gonic/gin"
	"github.com/pingcap/dbaas/billing2/utils/log"
	"github.com/pingcap/dbaas/billing2/utils/request"
	"github.com/pingcap/errors"
	"github.com/tidbcloud/tiinf/sdk/auditlog"
	"go.uber.org/zap"
)

func recoverIfPanic() {
	// if panic on details generating, we should not block the user path
	if r := recover(); r != nil {
		err := errors.WithStack(fmt.Errorf("%v", r))
		log.Error("failed to generate audit log detail ", zap.Error(err))
	}
}

func Log(typ auditlog.EventType, gCtx *gin.Context, tenantID uint, details *auditlog.Details, err error) {
	defer recoverIfPanic()
	if !request.SourceFromConsole(gCtx.Request) {
		return
	}
	ctx := context.Background()
	if details == nil {
		details = &auditlog.Details{}
	}
	details.SetError(err)
	e := auditlog.NewEvent(ctx, typ).ParseGIN(gCtx).SetOrgID(uint64(tenantID)).SetDetails(details.Build()).ParseGIN(gCtx).SetResult(err == nil).Submit()
	if e != nil {
		log.Error("failed to log audit-log ", zap.Error(e), zap.Int("EventType", int(typ)))
	}
}
