// Code generated by ent, DO NOT EDIT.

package ent

import (
	"context"
	"errors"
	"fmt"
	"log"
	"reflect"

	"github.com/TSELab/astra/internal/store/ent/migrate"

	"entgo.io/ent"
	"entgo.io/ent/dialect"
	"entgo.io/ent/dialect/sql"
	"github.com/TSELab/astra/internal/store/ent/artifact"
	"github.com/TSELab/astra/internal/store/ent/edge"
	"github.com/TSELab/astra/internal/store/ent/principal"
	"github.com/TSELab/astra/internal/store/ent/resource"
	"github.com/TSELab/astra/internal/store/ent/step"
)

// Client is the client that holds all ent builders.
type Client struct {
	config
	// Schema is the client for creating, migrating and dropping schema.
	Schema *migrate.Schema
	// Artifact is the client for interacting with the Artifact builders.
	Artifact *ArtifactClient
	// Edge is the client for interacting with the Edge builders.
	Edge *EdgeClient
	// Principal is the client for interacting with the Principal builders.
	Principal *PrincipalClient
	// Resource is the client for interacting with the Resource builders.
	Resource *ResourceClient
	// Step is the client for interacting with the Step builders.
	Step *StepClient
}

// NewClient creates a new client configured with the given options.
func NewClient(opts ...Option) *Client {
	client := &Client{config: newConfig(opts...)}
	client.init()
	return client
}

func (c *Client) init() {
	c.Schema = migrate.NewSchema(c.driver)
	c.Artifact = NewArtifactClient(c.config)
	c.Edge = NewEdgeClient(c.config)
	c.Principal = NewPrincipalClient(c.config)
	c.Resource = NewResourceClient(c.config)
	c.Step = NewStepClient(c.config)
}

type (
	// config is the configuration for the client and its builder.
	config struct {
		// driver used for executing database requests.
		driver dialect.Driver
		// debug enable a debug logging.
		debug bool
		// log used for logging on debug mode.
		log func(...any)
		// hooks to execute on mutations.
		hooks *hooks
		// interceptors to execute on queries.
		inters *inters
	}
	// Option function to configure the client.
	Option func(*config)
)

// newConfig creates a new config for the client.
func newConfig(opts ...Option) config {
	cfg := config{log: log.Println, hooks: &hooks{}, inters: &inters{}}
	cfg.options(opts...)
	return cfg
}

// options applies the options on the config object.
func (c *config) options(opts ...Option) {
	for _, opt := range opts {
		opt(c)
	}
	if c.debug {
		c.driver = dialect.Debug(c.driver, c.log)
	}
}

// Debug enables debug logging on the ent.Driver.
func Debug() Option {
	return func(c *config) {
		c.debug = true
	}
}

// Log sets the logging function for debug mode.
func Log(fn func(...any)) Option {
	return func(c *config) {
		c.log = fn
	}
}

// Driver configures the client driver.
func Driver(driver dialect.Driver) Option {
	return func(c *config) {
		c.driver = driver
	}
}

// Open opens a database/sql.DB specified by the driver name and
// the data source name, and returns a new client attached to it.
// Optional parameters can be added for configuring the client.
func Open(driverName, dataSourceName string, options ...Option) (*Client, error) {
	switch driverName {
	case dialect.MySQL, dialect.Postgres, dialect.SQLite:
		drv, err := sql.Open(driverName, dataSourceName)
		if err != nil {
			return nil, err
		}
		return NewClient(append(options, Driver(drv))...), nil
	default:
		return nil, fmt.Errorf("unsupported driver: %q", driverName)
	}
}

// ErrTxStarted is returned when trying to start a new transaction from a transactional client.
var ErrTxStarted = errors.New("ent: cannot start a transaction within a transaction")

// Tx returns a new transactional client. The provided context
// is used until the transaction is committed or rolled back.
func (c *Client) Tx(ctx context.Context) (*Tx, error) {
	if _, ok := c.driver.(*txDriver); ok {
		return nil, ErrTxStarted
	}
	tx, err := newTx(ctx, c.driver)
	if err != nil {
		return nil, fmt.Errorf("ent: starting a transaction: %w", err)
	}
	cfg := c.config
	cfg.driver = tx
	return &Tx{
		ctx:       ctx,
		config:    cfg,
		Artifact:  NewArtifactClient(cfg),
		Edge:      NewEdgeClient(cfg),
		Principal: NewPrincipalClient(cfg),
		Resource:  NewResourceClient(cfg),
		Step:      NewStepClient(cfg),
	}, nil
}

// BeginTx returns a transactional client with specified options.
func (c *Client) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
	if _, ok := c.driver.(*txDriver); ok {
		return nil, errors.New("ent: cannot start a transaction within a transaction")
	}
	tx, err := c.driver.(interface {
		BeginTx(context.Context, *sql.TxOptions) (dialect.Tx, error)
	}).BeginTx(ctx, opts)
	if err != nil {
		return nil, fmt.Errorf("ent: starting a transaction: %w", err)
	}
	cfg := c.config
	cfg.driver = &txDriver{tx: tx, drv: c.driver}
	return &Tx{
		ctx:       ctx,
		config:    cfg,
		Artifact:  NewArtifactClient(cfg),
		Edge:      NewEdgeClient(cfg),
		Principal: NewPrincipalClient(cfg),
		Resource:  NewResourceClient(cfg),
		Step:      NewStepClient(cfg),
	}, nil
}

// Debug returns a new debug-client. It's used to get verbose logging on specific operations.
//
//	client.Debug().
//		Artifact.
//		Query().
//		Count(ctx)
func (c *Client) Debug() *Client {
	if c.debug {
		return c
	}
	cfg := c.config
	cfg.driver = dialect.Debug(c.driver, c.log)
	client := &Client{config: cfg}
	client.init()
	return client
}

// Close closes the database connection and prevents new queries from starting.
func (c *Client) Close() error {
	return c.driver.Close()
}

// Use adds the mutation hooks to all the entity clients.
// In order to add hooks to a specific client, call: `client.Node.Use(...)`.
func (c *Client) Use(hooks ...Hook) {
	c.Artifact.Use(hooks...)
	c.Edge.Use(hooks...)
	c.Principal.Use(hooks...)
	c.Resource.Use(hooks...)
	c.Step.Use(hooks...)
}

// Intercept adds the query interceptors to all the entity clients.
// In order to add interceptors to a specific client, call: `client.Node.Intercept(...)`.
func (c *Client) Intercept(interceptors ...Interceptor) {
	c.Artifact.Intercept(interceptors...)
	c.Edge.Intercept(interceptors...)
	c.Principal.Intercept(interceptors...)
	c.Resource.Intercept(interceptors...)
	c.Step.Intercept(interceptors...)
}

// Mutate implements the ent.Mutator interface.
func (c *Client) Mutate(ctx context.Context, m Mutation) (Value, error) {
	switch m := m.(type) {
	case *ArtifactMutation:
		return c.Artifact.mutate(ctx, m)
	case *EdgeMutation:
		return c.Edge.mutate(ctx, m)
	case *PrincipalMutation:
		return c.Principal.mutate(ctx, m)
	case *ResourceMutation:
		return c.Resource.mutate(ctx, m)
	case *StepMutation:
		return c.Step.mutate(ctx, m)
	default:
		return nil, fmt.Errorf("ent: unknown mutation type %T", m)
	}
}

// ArtifactClient is a client for the Artifact schema.
type ArtifactClient struct {
	config
}

// NewArtifactClient returns a client for the Artifact from the given config.
func NewArtifactClient(c config) *ArtifactClient {
	return &ArtifactClient{config: c}
}

// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `artifact.Hooks(f(g(h())))`.
func (c *ArtifactClient) Use(hooks ...Hook) {
	c.hooks.Artifact = append(c.hooks.Artifact, hooks...)
}

// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `artifact.Intercept(f(g(h())))`.
func (c *ArtifactClient) Intercept(interceptors ...Interceptor) {
	c.inters.Artifact = append(c.inters.Artifact, interceptors...)
}

// Create returns a builder for creating a Artifact entity.
func (c *ArtifactClient) Create() *ArtifactCreate {
	mutation := newArtifactMutation(c.config, OpCreate)
	return &ArtifactCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// CreateBulk returns a builder for creating a bulk of Artifact entities.
func (c *ArtifactClient) CreateBulk(builders ...*ArtifactCreate) *ArtifactCreateBulk {
	return &ArtifactCreateBulk{config: c.config, builders: builders}
}

// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *ArtifactClient) MapCreateBulk(slice any, setFunc func(*ArtifactCreate, int)) *ArtifactCreateBulk {
	rv := reflect.ValueOf(slice)
	if rv.Kind() != reflect.Slice {
		return &ArtifactCreateBulk{err: fmt.Errorf("calling to ArtifactClient.MapCreateBulk with wrong type %T, need slice", slice)}
	}
	builders := make([]*ArtifactCreate, rv.Len())
	for i := 0; i < rv.Len(); i++ {
		builders[i] = c.Create()
		setFunc(builders[i], i)
	}
	return &ArtifactCreateBulk{config: c.config, builders: builders}
}

// Update returns an update builder for Artifact.
func (c *ArtifactClient) Update() *ArtifactUpdate {
	mutation := newArtifactMutation(c.config, OpUpdate)
	return &ArtifactUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOne returns an update builder for the given entity.
func (c *ArtifactClient) UpdateOne(_m *Artifact) *ArtifactUpdateOne {
	mutation := newArtifactMutation(c.config, OpUpdateOne, withArtifact(_m))
	return &ArtifactUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOneID returns an update builder for the given id.
func (c *ArtifactClient) UpdateOneID(id int) *ArtifactUpdateOne {
	mutation := newArtifactMutation(c.config, OpUpdateOne, withArtifactID(id))
	return &ArtifactUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// Delete returns a delete builder for Artifact.
func (c *ArtifactClient) Delete() *ArtifactDelete {
	mutation := newArtifactMutation(c.config, OpDelete)
	return &ArtifactDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// DeleteOne returns a builder for deleting the given entity.
func (c *ArtifactClient) DeleteOne(_m *Artifact) *ArtifactDeleteOne {
	return c.DeleteOneID(_m.ID)
}

// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *ArtifactClient) DeleteOneID(id int) *ArtifactDeleteOne {
	builder := c.Delete().Where(artifact.ID(id))
	builder.mutation.id = &id
	builder.mutation.op = OpDeleteOne
	return &ArtifactDeleteOne{builder}
}

// Query returns a query builder for Artifact.
func (c *ArtifactClient) Query() *ArtifactQuery {
	return &ArtifactQuery{
		config: c.config,
		ctx:    &QueryContext{Type: TypeArtifact},
		inters: c.Interceptors(),
	}
}

// Get returns a Artifact entity by its id.
func (c *ArtifactClient) Get(ctx context.Context, id int) (*Artifact, error) {
	return c.Query().Where(artifact.ID(id)).Only(ctx)
}

// GetX is like Get, but panics if an error occurs.
func (c *ArtifactClient) GetX(ctx context.Context, id int) *Artifact {
	obj, err := c.Get(ctx, id)
	if err != nil {
		panic(err)
	}
	return obj
}

// Hooks returns the client hooks.
func (c *ArtifactClient) Hooks() []Hook {
	return c.hooks.Artifact
}

// Interceptors returns the client interceptors.
func (c *ArtifactClient) Interceptors() []Interceptor {
	return c.inters.Artifact
}

func (c *ArtifactClient) mutate(ctx context.Context, m *ArtifactMutation) (Value, error) {
	switch m.Op() {
	case OpCreate:
		return (&ArtifactCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdate:
		return (&ArtifactUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdateOne:
		return (&ArtifactUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpDelete, OpDeleteOne:
		return (&ArtifactDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
	default:
		return nil, fmt.Errorf("ent: unknown Artifact mutation op: %q", m.Op())
	}
}

// EdgeClient is a client for the Edge schema.
type EdgeClient struct {
	config
}

// NewEdgeClient returns a client for the Edge from the given config.
func NewEdgeClient(c config) *EdgeClient {
	return &EdgeClient{config: c}
}

// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `edge.Hooks(f(g(h())))`.
func (c *EdgeClient) Use(hooks ...Hook) {
	c.hooks.Edge = append(c.hooks.Edge, hooks...)
}

// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `edge.Intercept(f(g(h())))`.
func (c *EdgeClient) Intercept(interceptors ...Interceptor) {
	c.inters.Edge = append(c.inters.Edge, interceptors...)
}

// Create returns a builder for creating a Edge entity.
func (c *EdgeClient) Create() *EdgeCreate {
	mutation := newEdgeMutation(c.config, OpCreate)
	return &EdgeCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// CreateBulk returns a builder for creating a bulk of Edge entities.
func (c *EdgeClient) CreateBulk(builders ...*EdgeCreate) *EdgeCreateBulk {
	return &EdgeCreateBulk{config: c.config, builders: builders}
}

// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *EdgeClient) MapCreateBulk(slice any, setFunc func(*EdgeCreate, int)) *EdgeCreateBulk {
	rv := reflect.ValueOf(slice)
	if rv.Kind() != reflect.Slice {
		return &EdgeCreateBulk{err: fmt.Errorf("calling to EdgeClient.MapCreateBulk with wrong type %T, need slice", slice)}
	}
	builders := make([]*EdgeCreate, rv.Len())
	for i := 0; i < rv.Len(); i++ {
		builders[i] = c.Create()
		setFunc(builders[i], i)
	}
	return &EdgeCreateBulk{config: c.config, builders: builders}
}

// Update returns an update builder for Edge.
func (c *EdgeClient) Update() *EdgeUpdate {
	mutation := newEdgeMutation(c.config, OpUpdate)
	return &EdgeUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOne returns an update builder for the given entity.
func (c *EdgeClient) UpdateOne(_m *Edge) *EdgeUpdateOne {
	mutation := newEdgeMutation(c.config, OpUpdateOne, withEdge(_m))
	return &EdgeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOneID returns an update builder for the given id.
func (c *EdgeClient) UpdateOneID(id int) *EdgeUpdateOne {
	mutation := newEdgeMutation(c.config, OpUpdateOne, withEdgeID(id))
	return &EdgeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// Delete returns a delete builder for Edge.
func (c *EdgeClient) Delete() *EdgeDelete {
	mutation := newEdgeMutation(c.config, OpDelete)
	return &EdgeDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// DeleteOne returns a builder for deleting the given entity.
func (c *EdgeClient) DeleteOne(_m *Edge) *EdgeDeleteOne {
	return c.DeleteOneID(_m.ID)
}

// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *EdgeClient) DeleteOneID(id int) *EdgeDeleteOne {
	builder := c.Delete().Where(edge.ID(id))
	builder.mutation.id = &id
	builder.mutation.op = OpDeleteOne
	return &EdgeDeleteOne{builder}
}

// Query returns a query builder for Edge.
func (c *EdgeClient) Query() *EdgeQuery {
	return &EdgeQuery{
		config: c.config,
		ctx:    &QueryContext{Type: TypeEdge},
		inters: c.Interceptors(),
	}
}

// Get returns a Edge entity by its id.
func (c *EdgeClient) Get(ctx context.Context, id int) (*Edge, error) {
	return c.Query().Where(edge.ID(id)).Only(ctx)
}

// GetX is like Get, but panics if an error occurs.
func (c *EdgeClient) GetX(ctx context.Context, id int) *Edge {
	obj, err := c.Get(ctx, id)
	if err != nil {
		panic(err)
	}
	return obj
}

// Hooks returns the client hooks.
func (c *EdgeClient) Hooks() []Hook {
	return c.hooks.Edge
}

// Interceptors returns the client interceptors.
func (c *EdgeClient) Interceptors() []Interceptor {
	return c.inters.Edge
}

func (c *EdgeClient) mutate(ctx context.Context, m *EdgeMutation) (Value, error) {
	switch m.Op() {
	case OpCreate:
		return (&EdgeCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdate:
		return (&EdgeUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdateOne:
		return (&EdgeUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpDelete, OpDeleteOne:
		return (&EdgeDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
	default:
		return nil, fmt.Errorf("ent: unknown Edge mutation op: %q", m.Op())
	}
}

// PrincipalClient is a client for the Principal schema.
type PrincipalClient struct {
	config
}

// NewPrincipalClient returns a client for the Principal from the given config.
func NewPrincipalClient(c config) *PrincipalClient {
	return &PrincipalClient{config: c}
}

// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `principal.Hooks(f(g(h())))`.
func (c *PrincipalClient) Use(hooks ...Hook) {
	c.hooks.Principal = append(c.hooks.Principal, hooks...)
}

// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `principal.Intercept(f(g(h())))`.
func (c *PrincipalClient) Intercept(interceptors ...Interceptor) {
	c.inters.Principal = append(c.inters.Principal, interceptors...)
}

// Create returns a builder for creating a Principal entity.
func (c *PrincipalClient) Create() *PrincipalCreate {
	mutation := newPrincipalMutation(c.config, OpCreate)
	return &PrincipalCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// CreateBulk returns a builder for creating a bulk of Principal entities.
func (c *PrincipalClient) CreateBulk(builders ...*PrincipalCreate) *PrincipalCreateBulk {
	return &PrincipalCreateBulk{config: c.config, builders: builders}
}

// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *PrincipalClient) MapCreateBulk(slice any, setFunc func(*PrincipalCreate, int)) *PrincipalCreateBulk {
	rv := reflect.ValueOf(slice)
	if rv.Kind() != reflect.Slice {
		return &PrincipalCreateBulk{err: fmt.Errorf("calling to PrincipalClient.MapCreateBulk with wrong type %T, need slice", slice)}
	}
	builders := make([]*PrincipalCreate, rv.Len())
	for i := 0; i < rv.Len(); i++ {
		builders[i] = c.Create()
		setFunc(builders[i], i)
	}
	return &PrincipalCreateBulk{config: c.config, builders: builders}
}

// Update returns an update builder for Principal.
func (c *PrincipalClient) Update() *PrincipalUpdate {
	mutation := newPrincipalMutation(c.config, OpUpdate)
	return &PrincipalUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOne returns an update builder for the given entity.
func (c *PrincipalClient) UpdateOne(_m *Principal) *PrincipalUpdateOne {
	mutation := newPrincipalMutation(c.config, OpUpdateOne, withPrincipal(_m))
	return &PrincipalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOneID returns an update builder for the given id.
func (c *PrincipalClient) UpdateOneID(id int) *PrincipalUpdateOne {
	mutation := newPrincipalMutation(c.config, OpUpdateOne, withPrincipalID(id))
	return &PrincipalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// Delete returns a delete builder for Principal.
func (c *PrincipalClient) Delete() *PrincipalDelete {
	mutation := newPrincipalMutation(c.config, OpDelete)
	return &PrincipalDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// DeleteOne returns a builder for deleting the given entity.
func (c *PrincipalClient) DeleteOne(_m *Principal) *PrincipalDeleteOne {
	return c.DeleteOneID(_m.ID)
}

// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *PrincipalClient) DeleteOneID(id int) *PrincipalDeleteOne {
	builder := c.Delete().Where(principal.ID(id))
	builder.mutation.id = &id
	builder.mutation.op = OpDeleteOne
	return &PrincipalDeleteOne{builder}
}

// Query returns a query builder for Principal.
func (c *PrincipalClient) Query() *PrincipalQuery {
	return &PrincipalQuery{
		config: c.config,
		ctx:    &QueryContext{Type: TypePrincipal},
		inters: c.Interceptors(),
	}
}

// Get returns a Principal entity by its id.
func (c *PrincipalClient) Get(ctx context.Context, id int) (*Principal, error) {
	return c.Query().Where(principal.ID(id)).Only(ctx)
}

// GetX is like Get, but panics if an error occurs.
func (c *PrincipalClient) GetX(ctx context.Context, id int) *Principal {
	obj, err := c.Get(ctx, id)
	if err != nil {
		panic(err)
	}
	return obj
}

// Hooks returns the client hooks.
func (c *PrincipalClient) Hooks() []Hook {
	return c.hooks.Principal
}

// Interceptors returns the client interceptors.
func (c *PrincipalClient) Interceptors() []Interceptor {
	return c.inters.Principal
}

func (c *PrincipalClient) mutate(ctx context.Context, m *PrincipalMutation) (Value, error) {
	switch m.Op() {
	case OpCreate:
		return (&PrincipalCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdate:
		return (&PrincipalUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdateOne:
		return (&PrincipalUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpDelete, OpDeleteOne:
		return (&PrincipalDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
	default:
		return nil, fmt.Errorf("ent: unknown Principal mutation op: %q", m.Op())
	}
}

// ResourceClient is a client for the Resource schema.
type ResourceClient struct {
	config
}

// NewResourceClient returns a client for the Resource from the given config.
func NewResourceClient(c config) *ResourceClient {
	return &ResourceClient{config: c}
}

// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `resource.Hooks(f(g(h())))`.
func (c *ResourceClient) Use(hooks ...Hook) {
	c.hooks.Resource = append(c.hooks.Resource, hooks...)
}

// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `resource.Intercept(f(g(h())))`.
func (c *ResourceClient) Intercept(interceptors ...Interceptor) {
	c.inters.Resource = append(c.inters.Resource, interceptors...)
}

// Create returns a builder for creating a Resource entity.
func (c *ResourceClient) Create() *ResourceCreate {
	mutation := newResourceMutation(c.config, OpCreate)
	return &ResourceCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// CreateBulk returns a builder for creating a bulk of Resource entities.
func (c *ResourceClient) CreateBulk(builders ...*ResourceCreate) *ResourceCreateBulk {
	return &ResourceCreateBulk{config: c.config, builders: builders}
}

// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *ResourceClient) MapCreateBulk(slice any, setFunc func(*ResourceCreate, int)) *ResourceCreateBulk {
	rv := reflect.ValueOf(slice)
	if rv.Kind() != reflect.Slice {
		return &ResourceCreateBulk{err: fmt.Errorf("calling to ResourceClient.MapCreateBulk with wrong type %T, need slice", slice)}
	}
	builders := make([]*ResourceCreate, rv.Len())
	for i := 0; i < rv.Len(); i++ {
		builders[i] = c.Create()
		setFunc(builders[i], i)
	}
	return &ResourceCreateBulk{config: c.config, builders: builders}
}

// Update returns an update builder for Resource.
func (c *ResourceClient) Update() *ResourceUpdate {
	mutation := newResourceMutation(c.config, OpUpdate)
	return &ResourceUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOne returns an update builder for the given entity.
func (c *ResourceClient) UpdateOne(_m *Resource) *ResourceUpdateOne {
	mutation := newResourceMutation(c.config, OpUpdateOne, withResource(_m))
	return &ResourceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOneID returns an update builder for the given id.
func (c *ResourceClient) UpdateOneID(id int) *ResourceUpdateOne {
	mutation := newResourceMutation(c.config, OpUpdateOne, withResourceID(id))
	return &ResourceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// Delete returns a delete builder for Resource.
func (c *ResourceClient) Delete() *ResourceDelete {
	mutation := newResourceMutation(c.config, OpDelete)
	return &ResourceDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// DeleteOne returns a builder for deleting the given entity.
func (c *ResourceClient) DeleteOne(_m *Resource) *ResourceDeleteOne {
	return c.DeleteOneID(_m.ID)
}

// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *ResourceClient) DeleteOneID(id int) *ResourceDeleteOne {
	builder := c.Delete().Where(resource.ID(id))
	builder.mutation.id = &id
	builder.mutation.op = OpDeleteOne
	return &ResourceDeleteOne{builder}
}

// Query returns a query builder for Resource.
func (c *ResourceClient) Query() *ResourceQuery {
	return &ResourceQuery{
		config: c.config,
		ctx:    &QueryContext{Type: TypeResource},
		inters: c.Interceptors(),
	}
}

// Get returns a Resource entity by its id.
func (c *ResourceClient) Get(ctx context.Context, id int) (*Resource, error) {
	return c.Query().Where(resource.ID(id)).Only(ctx)
}

// GetX is like Get, but panics if an error occurs.
func (c *ResourceClient) GetX(ctx context.Context, id int) *Resource {
	obj, err := c.Get(ctx, id)
	if err != nil {
		panic(err)
	}
	return obj
}

// Hooks returns the client hooks.
func (c *ResourceClient) Hooks() []Hook {
	return c.hooks.Resource
}

// Interceptors returns the client interceptors.
func (c *ResourceClient) Interceptors() []Interceptor {
	return c.inters.Resource
}

func (c *ResourceClient) mutate(ctx context.Context, m *ResourceMutation) (Value, error) {
	switch m.Op() {
	case OpCreate:
		return (&ResourceCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdate:
		return (&ResourceUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdateOne:
		return (&ResourceUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpDelete, OpDeleteOne:
		return (&ResourceDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
	default:
		return nil, fmt.Errorf("ent: unknown Resource mutation op: %q", m.Op())
	}
}

// StepClient is a client for the Step schema.
type StepClient struct {
	config
}

// NewStepClient returns a client for the Step from the given config.
func NewStepClient(c config) *StepClient {
	return &StepClient{config: c}
}

// Use adds a list of mutation hooks to the hooks stack.
// A call to `Use(f, g, h)` equals to `step.Hooks(f(g(h())))`.
func (c *StepClient) Use(hooks ...Hook) {
	c.hooks.Step = append(c.hooks.Step, hooks...)
}

// Intercept adds a list of query interceptors to the interceptors stack.
// A call to `Intercept(f, g, h)` equals to `step.Intercept(f(g(h())))`.
func (c *StepClient) Intercept(interceptors ...Interceptor) {
	c.inters.Step = append(c.inters.Step, interceptors...)
}

// Create returns a builder for creating a Step entity.
func (c *StepClient) Create() *StepCreate {
	mutation := newStepMutation(c.config, OpCreate)
	return &StepCreate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// CreateBulk returns a builder for creating a bulk of Step entities.
func (c *StepClient) CreateBulk(builders ...*StepCreate) *StepCreateBulk {
	return &StepCreateBulk{config: c.config, builders: builders}
}

// MapCreateBulk creates a bulk creation builder from the given slice. For each item in the slice, the function creates
// a builder and applies setFunc on it.
func (c *StepClient) MapCreateBulk(slice any, setFunc func(*StepCreate, int)) *StepCreateBulk {
	rv := reflect.ValueOf(slice)
	if rv.Kind() != reflect.Slice {
		return &StepCreateBulk{err: fmt.Errorf("calling to StepClient.MapCreateBulk with wrong type %T, need slice", slice)}
	}
	builders := make([]*StepCreate, rv.Len())
	for i := 0; i < rv.Len(); i++ {
		builders[i] = c.Create()
		setFunc(builders[i], i)
	}
	return &StepCreateBulk{config: c.config, builders: builders}
}

// Update returns an update builder for Step.
func (c *StepClient) Update() *StepUpdate {
	mutation := newStepMutation(c.config, OpUpdate)
	return &StepUpdate{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOne returns an update builder for the given entity.
func (c *StepClient) UpdateOne(_m *Step) *StepUpdateOne {
	mutation := newStepMutation(c.config, OpUpdateOne, withStep(_m))
	return &StepUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// UpdateOneID returns an update builder for the given id.
func (c *StepClient) UpdateOneID(id int) *StepUpdateOne {
	mutation := newStepMutation(c.config, OpUpdateOne, withStepID(id))
	return &StepUpdateOne{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// Delete returns a delete builder for Step.
func (c *StepClient) Delete() *StepDelete {
	mutation := newStepMutation(c.config, OpDelete)
	return &StepDelete{config: c.config, hooks: c.Hooks(), mutation: mutation}
}

// DeleteOne returns a builder for deleting the given entity.
func (c *StepClient) DeleteOne(_m *Step) *StepDeleteOne {
	return c.DeleteOneID(_m.ID)
}

// DeleteOneID returns a builder for deleting the given entity by its id.
func (c *StepClient) DeleteOneID(id int) *StepDeleteOne {
	builder := c.Delete().Where(step.ID(id))
	builder.mutation.id = &id
	builder.mutation.op = OpDeleteOne
	return &StepDeleteOne{builder}
}

// Query returns a query builder for Step.
func (c *StepClient) Query() *StepQuery {
	return &StepQuery{
		config: c.config,
		ctx:    &QueryContext{Type: TypeStep},
		inters: c.Interceptors(),
	}
}

// Get returns a Step entity by its id.
func (c *StepClient) Get(ctx context.Context, id int) (*Step, error) {
	return c.Query().Where(step.ID(id)).Only(ctx)
}

// GetX is like Get, but panics if an error occurs.
func (c *StepClient) GetX(ctx context.Context, id int) *Step {
	obj, err := c.Get(ctx, id)
	if err != nil {
		panic(err)
	}
	return obj
}

// Hooks returns the client hooks.
func (c *StepClient) Hooks() []Hook {
	return c.hooks.Step
}

// Interceptors returns the client interceptors.
func (c *StepClient) Interceptors() []Interceptor {
	return c.inters.Step
}

func (c *StepClient) mutate(ctx context.Context, m *StepMutation) (Value, error) {
	switch m.Op() {
	case OpCreate:
		return (&StepCreate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdate:
		return (&StepUpdate{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpUpdateOne:
		return (&StepUpdateOne{config: c.config, hooks: c.Hooks(), mutation: m}).Save(ctx)
	case OpDelete, OpDeleteOne:
		return (&StepDelete{config: c.config, hooks: c.Hooks(), mutation: m}).Exec(ctx)
	default:
		return nil, fmt.Errorf("ent: unknown Step mutation op: %q", m.Op())
	}
}

// hooks and interceptors per client, for fast access.
type (
	hooks struct {
		Artifact, Edge, Principal, Resource, Step []ent.Hook
	}
	inters struct {
		Artifact, Edge, Principal, Resource, Step []ent.Interceptor
	}
)
