// Code generated by ent, DO NOT EDIT.

package hook

import (
	"context"
	"fmt"

	"github.com/lightsparkdev/spark/so/ent"
)

// The BlockHeightFunc type is an adapter to allow the use of ordinary
// function as BlockHeight mutator.
type BlockHeightFunc func(context.Context, *ent.BlockHeightMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f BlockHeightFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.BlockHeightMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.BlockHeightMutation", m)
}

// The CooperativeExitFunc type is an adapter to allow the use of ordinary
// function as CooperativeExit mutator.
type CooperativeExitFunc func(context.Context, *ent.CooperativeExitMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f CooperativeExitFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.CooperativeExitMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.CooperativeExitMutation", m)
}

// The DepositAddressFunc type is an adapter to allow the use of ordinary
// function as DepositAddress mutator.
type DepositAddressFunc func(context.Context, *ent.DepositAddressMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f DepositAddressFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.DepositAddressMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.DepositAddressMutation", m)
}

// The EntityDkgKeyFunc type is an adapter to allow the use of ordinary
// function as EntityDkgKey mutator.
type EntityDkgKeyFunc func(context.Context, *ent.EntityDkgKeyMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f EntityDkgKeyFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.EntityDkgKeyMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.EntityDkgKeyMutation", m)
}

// The GossipFunc type is an adapter to allow the use of ordinary
// function as Gossip mutator.
type GossipFunc func(context.Context, *ent.GossipMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f GossipFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.GossipMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.GossipMutation", m)
}

// The L1TokenCreateFunc type is an adapter to allow the use of ordinary
// function as L1TokenCreate mutator.
type L1TokenCreateFunc func(context.Context, *ent.L1TokenCreateMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f L1TokenCreateFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.L1TokenCreateMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.L1TokenCreateMutation", m)
}

// The PaymentIntentFunc type is an adapter to allow the use of ordinary
// function as PaymentIntent mutator.
type PaymentIntentFunc func(context.Context, *ent.PaymentIntentMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f PaymentIntentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.PaymentIntentMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PaymentIntentMutation", m)
}

// The PendingSendTransferFunc type is an adapter to allow the use of ordinary
// function as PendingSendTransfer mutator.
type PendingSendTransferFunc func(context.Context, *ent.PendingSendTransferMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f PendingSendTransferFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.PendingSendTransferMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PendingSendTransferMutation", m)
}

// The PreimageRequestFunc type is an adapter to allow the use of ordinary
// function as PreimageRequest mutator.
type PreimageRequestFunc func(context.Context, *ent.PreimageRequestMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f PreimageRequestFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.PreimageRequestMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PreimageRequestMutation", m)
}

// The PreimageShareFunc type is an adapter to allow the use of ordinary
// function as PreimageShare mutator.
type PreimageShareFunc func(context.Context, *ent.PreimageShareMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f PreimageShareFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.PreimageShareMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.PreimageShareMutation", m)
}

// The SigningCommitmentFunc type is an adapter to allow the use of ordinary
// function as SigningCommitment mutator.
type SigningCommitmentFunc func(context.Context, *ent.SigningCommitmentMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f SigningCommitmentFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.SigningCommitmentMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SigningCommitmentMutation", m)
}

// The SigningKeyshareFunc type is an adapter to allow the use of ordinary
// function as SigningKeyshare mutator.
type SigningKeyshareFunc func(context.Context, *ent.SigningKeyshareMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f SigningKeyshareFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.SigningKeyshareMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SigningKeyshareMutation", m)
}

// The SigningNonceFunc type is an adapter to allow the use of ordinary
// function as SigningNonce mutator.
type SigningNonceFunc func(context.Context, *ent.SigningNonceMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f SigningNonceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.SigningNonceMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SigningNonceMutation", m)
}

// The SparkInvoiceFunc type is an adapter to allow the use of ordinary
// function as SparkInvoice mutator.
type SparkInvoiceFunc func(context.Context, *ent.SparkInvoiceMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f SparkInvoiceFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.SparkInvoiceMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.SparkInvoiceMutation", m)
}

// The TokenCreateFunc type is an adapter to allow the use of ordinary
// function as TokenCreate mutator.
type TokenCreateFunc func(context.Context, *ent.TokenCreateMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenCreateFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenCreateMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenCreateMutation", m)
}

// The TokenFreezeFunc type is an adapter to allow the use of ordinary
// function as TokenFreeze mutator.
type TokenFreezeFunc func(context.Context, *ent.TokenFreezeMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenFreezeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenFreezeMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenFreezeMutation", m)
}

// The TokenMintFunc type is an adapter to allow the use of ordinary
// function as TokenMint mutator.
type TokenMintFunc func(context.Context, *ent.TokenMintMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenMintFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenMintMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenMintMutation", m)
}

// The TokenOutputFunc type is an adapter to allow the use of ordinary
// function as TokenOutput mutator.
type TokenOutputFunc func(context.Context, *ent.TokenOutputMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenOutputFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenOutputMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenOutputMutation", m)
}

// The TokenPartialRevocationSecretShareFunc type is an adapter to allow the use of ordinary
// function as TokenPartialRevocationSecretShare mutator.
type TokenPartialRevocationSecretShareFunc func(context.Context, *ent.TokenPartialRevocationSecretShareMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenPartialRevocationSecretShareFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenPartialRevocationSecretShareMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenPartialRevocationSecretShareMutation", m)
}

// The TokenTransactionFunc type is an adapter to allow the use of ordinary
// function as TokenTransaction mutator.
type TokenTransactionFunc func(context.Context, *ent.TokenTransactionMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenTransactionFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenTransactionMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenTransactionMutation", m)
}

// The TokenTransactionPeerSignatureFunc type is an adapter to allow the use of ordinary
// function as TokenTransactionPeerSignature mutator.
type TokenTransactionPeerSignatureFunc func(context.Context, *ent.TokenTransactionPeerSignatureMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TokenTransactionPeerSignatureFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TokenTransactionPeerSignatureMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TokenTransactionPeerSignatureMutation", m)
}

// The TransferFunc type is an adapter to allow the use of ordinary
// function as Transfer mutator.
type TransferFunc func(context.Context, *ent.TransferMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TransferFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TransferMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TransferMutation", m)
}

// The TransferLeafFunc type is an adapter to allow the use of ordinary
// function as TransferLeaf mutator.
type TransferLeafFunc func(context.Context, *ent.TransferLeafMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TransferLeafFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TransferLeafMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TransferLeafMutation", m)
}

// The TreeFunc type is an adapter to allow the use of ordinary
// function as Tree mutator.
type TreeFunc func(context.Context, *ent.TreeMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TreeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TreeMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TreeMutation", m)
}

// The TreeNodeFunc type is an adapter to allow the use of ordinary
// function as TreeNode mutator.
type TreeNodeFunc func(context.Context, *ent.TreeNodeMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f TreeNodeFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.TreeNodeMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.TreeNodeMutation", m)
}

// The UserSignedTransactionFunc type is an adapter to allow the use of ordinary
// function as UserSignedTransaction mutator.
type UserSignedTransactionFunc func(context.Context, *ent.UserSignedTransactionMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f UserSignedTransactionFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.UserSignedTransactionMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UserSignedTransactionMutation", m)
}

// The UtxoFunc type is an adapter to allow the use of ordinary
// function as Utxo mutator.
type UtxoFunc func(context.Context, *ent.UtxoMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f UtxoFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.UtxoMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UtxoMutation", m)
}

// The UtxoSwapFunc type is an adapter to allow the use of ordinary
// function as UtxoSwap mutator.
type UtxoSwapFunc func(context.Context, *ent.UtxoSwapMutation) (ent.Value, error)

// Mutate calls f(ctx, m).
func (f UtxoSwapFunc) Mutate(ctx context.Context, m ent.Mutation) (ent.Value, error) {
	if mv, ok := m.(*ent.UtxoSwapMutation); ok {
		return f(ctx, mv)
	}
	return nil, fmt.Errorf("unexpected mutation type %T. expect *ent.UtxoSwapMutation", m)
}

// Condition is a hook condition function.
type Condition func(context.Context, ent.Mutation) bool

// And groups conditions with the AND operator.
func And(first, second Condition, rest ...Condition) Condition {
	return func(ctx context.Context, m ent.Mutation) bool {
		if !first(ctx, m) || !second(ctx, m) {
			return false
		}
		for _, cond := range rest {
			if !cond(ctx, m) {
				return false
			}
		}
		return true
	}
}

// Or groups conditions with the OR operator.
func Or(first, second Condition, rest ...Condition) Condition {
	return func(ctx context.Context, m ent.Mutation) bool {
		if first(ctx, m) || second(ctx, m) {
			return true
		}
		for _, cond := range rest {
			if cond(ctx, m) {
				return true
			}
		}
		return false
	}
}

// Not negates a given condition.
func Not(cond Condition) Condition {
	return func(ctx context.Context, m ent.Mutation) bool {
		return !cond(ctx, m)
	}
}

// HasOp is a condition testing mutation operation.
func HasOp(op ent.Op) Condition {
	return func(_ context.Context, m ent.Mutation) bool {
		return m.Op().Is(op)
	}
}

// HasAddedFields is a condition validating `.AddedField` on fields.
func HasAddedFields(field string, fields ...string) Condition {
	return func(_ context.Context, m ent.Mutation) bool {
		if _, exists := m.AddedField(field); !exists {
			return false
		}
		for _, field := range fields {
			if _, exists := m.AddedField(field); !exists {
				return false
			}
		}
		return true
	}
}

// HasClearedFields is a condition validating `.FieldCleared` on fields.
func HasClearedFields(field string, fields ...string) Condition {
	return func(_ context.Context, m ent.Mutation) bool {
		if exists := m.FieldCleared(field); !exists {
			return false
		}
		for _, field := range fields {
			if exists := m.FieldCleared(field); !exists {
				return false
			}
		}
		return true
	}
}

// HasFields is a condition validating `.Field` on fields.
func HasFields(field string, fields ...string) Condition {
	return func(_ context.Context, m ent.Mutation) bool {
		if _, exists := m.Field(field); !exists {
			return false
		}
		for _, field := range fields {
			if _, exists := m.Field(field); !exists {
				return false
			}
		}
		return true
	}
}

// If executes the given hook under condition.
//
//	hook.If(ComputeAverage, And(HasFields(...), HasAddedFields(...)))
func If(hk ent.Hook, cond Condition) ent.Hook {
	return func(next ent.Mutator) ent.Mutator {
		return ent.MutateFunc(func(ctx context.Context, m ent.Mutation) (ent.Value, error) {
			if cond(ctx, m) {
				return hk(next).Mutate(ctx, m)
			}
			return next.Mutate(ctx, m)
		})
	}
}

// On executes the given hook only for the given operation.
//
//	hook.On(Log, ent.Delete|ent.Create)
func On(hk ent.Hook, op ent.Op) ent.Hook {
	return If(hk, HasOp(op))
}

// Unless skips the given hook only for the given operation.
//
//	hook.Unless(Log, ent.Update|ent.UpdateOne)
func Unless(hk ent.Hook, op ent.Op) ent.Hook {
	return If(hk, Not(HasOp(op)))
}

// FixedError is a hook returning a fixed error.
func FixedError(err error) ent.Hook {
	return func(ent.Mutator) ent.Mutator {
		return ent.MutateFunc(func(context.Context, ent.Mutation) (ent.Value, error) {
			return nil, err
		})
	}
}

// Reject returns a hook that rejects all operations that match op.
//
//	func (T) Hooks() []ent.Hook {
//		return []ent.Hook{
//			Reject(ent.Delete|ent.Update),
//		}
//	}
func Reject(op ent.Op) ent.Hook {
	hk := FixedError(fmt.Errorf("%s operation is not allowed", op))
	return On(hk, op)
}

// Chain acts as a list of hooks and is effectively immutable.
// Once created, it will always hold the same set of hooks in the same order.
type Chain struct {
	hooks []ent.Hook
}

// NewChain creates a new chain of hooks.
func NewChain(hooks ...ent.Hook) Chain {
	return Chain{append([]ent.Hook(nil), hooks...)}
}

// Hook chains the list of hooks and returns the final hook.
func (c Chain) Hook() ent.Hook {
	return func(mutator ent.Mutator) ent.Mutator {
		for i := len(c.hooks) - 1; i >= 0; i-- {
			mutator = c.hooks[i](mutator)
		}
		return mutator
	}
}

// Append extends a chain, adding the specified hook
// as the last ones in the mutation flow.
func (c Chain) Append(hooks ...ent.Hook) Chain {
	newHooks := make([]ent.Hook, 0, len(c.hooks)+len(hooks))
	newHooks = append(newHooks, c.hooks...)
	newHooks = append(newHooks, hooks...)
	return Chain{newHooks}
}

// Extend extends a chain, adding the specified chain
// as the last ones in the mutation flow.
func (c Chain) Extend(chain Chain) Chain {
	return c.Append(chain.hooks...)
}
