package entx

import (
	"context"
	"fmt"
	"git.noahlan.cn/n-admin/n-admin-server/rpc/core/ent"
	"git.noahlan.cn/noahlan/ntool/nlog"
)

// WithTx uses transaction in ent.
func WithTx(ctx context.Context, client *ent.Client, fn func(tx *ent.Tx) error) error {
	tx, err := client.Tx(ctx)
	if err != nil {
		nlog.Errorw("failed to start transaction", nlog.Field("detail", err.Error()))
		return err
	}
	defer func() {
		if v := recover(); v != nil {
			_ = tx.Rollback()
			panic(v)
		}
	}()

	if err := fn(tx); err != nil {
		if rollbackErr := tx.Rollback(); rollbackErr != nil {
			err = fmt.Errorf("%w: rolling back transaction: %v", err, rollbackErr)
		}
		nlog.Errorw("errors occur in transaction", nlog.Field("detail", err.Error()))
		return err
	}
	if err := tx.Commit(); err != nil {
		nlog.Errorw("failed to commit transaction", nlog.Field("detail", err.Error()))
		return err
	}

	return nil
}
