// Code generated by ent, DO NOT EDIT.

package ent

import (
	"context"
	"errors"
	"fmt"
	"galileo/ent/container"

	"entgo.io/ent/dialect/sql/sqlgraph"
	"entgo.io/ent/schema/field"
)

// ContainerCreate is the builder for creating a Container entity.
type ContainerCreate struct {
	config
	mutation *ContainerMutation
	hooks    []Hook
}

// SetHostname sets the "hostname" field.
func (cc *ContainerCreate) SetHostname(s string) *ContainerCreate {
	cc.mutation.SetHostname(s)
	return cc
}

// SetDomainname sets the "domainname" field.
func (cc *ContainerCreate) SetDomainname(s string) *ContainerCreate {
	cc.mutation.SetDomainname(s)
	return cc
}

// SetUser sets the "user" field.
func (cc *ContainerCreate) SetUser(s string) *ContainerCreate {
	cc.mutation.SetUser(s)
	return cc
}

// SetNillableUser sets the "user" field if the given value is not nil.
func (cc *ContainerCreate) SetNillableUser(s *string) *ContainerCreate {
	if s != nil {
		cc.SetUser(*s)
	}
	return cc
}

// SetEnv sets the "env" field.
func (cc *ContainerCreate) SetEnv(s []string) *ContainerCreate {
	cc.mutation.SetEnv(s)
	return cc
}

// SetCmd sets the "cmd" field.
func (cc *ContainerCreate) SetCmd(s []string) *ContainerCreate {
	cc.mutation.SetCmd(s)
	return cc
}

// SetImage sets the "image" field.
func (cc *ContainerCreate) SetImage(s string) *ContainerCreate {
	cc.mutation.SetImage(s)
	return cc
}

// SetLabels sets the "labels" field.
func (cc *ContainerCreate) SetLabels(s []string) *ContainerCreate {
	cc.mutation.SetLabels(s)
	return cc
}

// SetVolumes sets the "volumes" field.
func (cc *ContainerCreate) SetVolumes(s []string) *ContainerCreate {
	cc.mutation.SetVolumes(s)
	return cc
}

// SetWorkingDir sets the "working_dir" field.
func (cc *ContainerCreate) SetWorkingDir(s string) *ContainerCreate {
	cc.mutation.SetWorkingDir(s)
	return cc
}

// SetNillableWorkingDir sets the "working_dir" field if the given value is not nil.
func (cc *ContainerCreate) SetNillableWorkingDir(s *string) *ContainerCreate {
	if s != nil {
		cc.SetWorkingDir(*s)
	}
	return cc
}

// SetEntrypoint sets the "entrypoint" field.
func (cc *ContainerCreate) SetEntrypoint(s []string) *ContainerCreate {
	cc.mutation.SetEntrypoint(s)
	return cc
}

// SetMACAddress sets the "mac_address" field.
func (cc *ContainerCreate) SetMACAddress(s string) *ContainerCreate {
	cc.mutation.SetMACAddress(s)
	return cc
}

// SetExposePorts sets the "expose_ports" field.
func (cc *ContainerCreate) SetExposePorts(s []string) *ContainerCreate {
	cc.mutation.SetExposePorts(s)
	return cc
}

// SetComposeFileURL sets the "compose_file_url" field.
func (cc *ContainerCreate) SetComposeFileURL(s string) *ContainerCreate {
	cc.mutation.SetComposeFileURL(s)
	return cc
}

// SetNillableComposeFileURL sets the "compose_file_url" field if the given value is not nil.
func (cc *ContainerCreate) SetNillableComposeFileURL(s *string) *ContainerCreate {
	if s != nil {
		cc.SetComposeFileURL(*s)
	}
	return cc
}

// SetDockerfileURL sets the "dockerfile_url" field.
func (cc *ContainerCreate) SetDockerfileURL(s string) *ContainerCreate {
	cc.mutation.SetDockerfileURL(s)
	return cc
}

// SetNillableDockerfileURL sets the "dockerfile_url" field if the given value is not nil.
func (cc *ContainerCreate) SetNillableDockerfileURL(s *string) *ContainerCreate {
	if s != nil {
		cc.SetDockerfileURL(*s)
	}
	return cc
}

// SetID sets the "id" field.
func (cc *ContainerCreate) SetID(s string) *ContainerCreate {
	cc.mutation.SetID(s)
	return cc
}

// Mutation returns the ContainerMutation object of the builder.
func (cc *ContainerCreate) Mutation() *ContainerMutation {
	return cc.mutation
}

// Save creates the Container in the database.
func (cc *ContainerCreate) Save(ctx context.Context) (*Container, error) {
	return withHooks[*Container, ContainerMutation](ctx, cc.sqlSave, cc.mutation, cc.hooks)
}

// SaveX calls Save and panics if Save returns an error.
func (cc *ContainerCreate) SaveX(ctx context.Context) *Container {
	v, err := cc.Save(ctx)
	if err != nil {
		panic(err)
	}
	return v
}

// Exec executes the query.
func (cc *ContainerCreate) Exec(ctx context.Context) error {
	_, err := cc.Save(ctx)
	return err
}

// ExecX is like Exec, but panics if an error occurs.
func (cc *ContainerCreate) ExecX(ctx context.Context) {
	if err := cc.Exec(ctx); err != nil {
		panic(err)
	}
}

// check runs all checks and user-defined validators on the builder.
func (cc *ContainerCreate) check() error {
	if _, ok := cc.mutation.Hostname(); !ok {
		return &ValidationError{Name: "hostname", err: errors.New(`ent: missing required field "Container.hostname"`)}
	}
	if v, ok := cc.mutation.Hostname(); ok {
		if err := container.HostnameValidator(v); err != nil {
			return &ValidationError{Name: "hostname", err: fmt.Errorf(`ent: validator failed for field "Container.hostname": %w`, err)}
		}
	}
	if _, ok := cc.mutation.Domainname(); !ok {
		return &ValidationError{Name: "domainname", err: errors.New(`ent: missing required field "Container.domainname"`)}
	}
	if v, ok := cc.mutation.Domainname(); ok {
		if err := container.DomainnameValidator(v); err != nil {
			return &ValidationError{Name: "domainname", err: fmt.Errorf(`ent: validator failed for field "Container.domainname": %w`, err)}
		}
	}
	if _, ok := cc.mutation.Image(); !ok {
		return &ValidationError{Name: "image", err: errors.New(`ent: missing required field "Container.image"`)}
	}
	if v, ok := cc.mutation.Image(); ok {
		if err := container.ImageValidator(v); err != nil {
			return &ValidationError{Name: "image", err: fmt.Errorf(`ent: validator failed for field "Container.image": %w`, err)}
		}
	}
	if _, ok := cc.mutation.MACAddress(); !ok {
		return &ValidationError{Name: "mac_address", err: errors.New(`ent: missing required field "Container.mac_address"`)}
	}
	if v, ok := cc.mutation.MACAddress(); ok {
		if err := container.MACAddressValidator(v); err != nil {
			return &ValidationError{Name: "mac_address", err: fmt.Errorf(`ent: validator failed for field "Container.mac_address": %w`, err)}
		}
	}
	if v, ok := cc.mutation.ID(); ok {
		if err := container.IDValidator(v); err != nil {
			return &ValidationError{Name: "id", err: fmt.Errorf(`ent: validator failed for field "Container.id": %w`, err)}
		}
	}
	return nil
}

func (cc *ContainerCreate) sqlSave(ctx context.Context) (*Container, error) {
	if err := cc.check(); err != nil {
		return nil, err
	}
	_node, _spec := cc.createSpec()
	if err := sqlgraph.CreateNode(ctx, cc.driver, _spec); err != nil {
		if sqlgraph.IsConstraintError(err) {
			err = &ConstraintError{msg: err.Error(), wrap: err}
		}
		return nil, err
	}
	if _spec.ID.Value != nil {
		if id, ok := _spec.ID.Value.(string); ok {
			_node.ID = id
		} else {
			return nil, fmt.Errorf("unexpected Container.ID type: %T", _spec.ID.Value)
		}
	}
	cc.mutation.id = &_node.ID
	cc.mutation.done = true
	return _node, nil
}

func (cc *ContainerCreate) createSpec() (*Container, *sqlgraph.CreateSpec) {
	var (
		_node = &Container{config: cc.config}
		_spec = sqlgraph.NewCreateSpec(container.Table, sqlgraph.NewFieldSpec(container.FieldID, field.TypeString))
	)
	if id, ok := cc.mutation.ID(); ok {
		_node.ID = id
		_spec.ID.Value = id
	}
	if value, ok := cc.mutation.Hostname(); ok {
		_spec.SetField(container.FieldHostname, field.TypeString, value)
		_node.Hostname = value
	}
	if value, ok := cc.mutation.Domainname(); ok {
		_spec.SetField(container.FieldDomainname, field.TypeString, value)
		_node.Domainname = value
	}
	if value, ok := cc.mutation.User(); ok {
		_spec.SetField(container.FieldUser, field.TypeString, value)
		_node.User = value
	}
	if value, ok := cc.mutation.Env(); ok {
		_spec.SetField(container.FieldEnv, field.TypeJSON, value)
		_node.Env = value
	}
	if value, ok := cc.mutation.Cmd(); ok {
		_spec.SetField(container.FieldCmd, field.TypeJSON, value)
		_node.Cmd = value
	}
	if value, ok := cc.mutation.Image(); ok {
		_spec.SetField(container.FieldImage, field.TypeString, value)
		_node.Image = value
	}
	if value, ok := cc.mutation.Labels(); ok {
		_spec.SetField(container.FieldLabels, field.TypeJSON, value)
		_node.Labels = value
	}
	if value, ok := cc.mutation.Volumes(); ok {
		_spec.SetField(container.FieldVolumes, field.TypeJSON, value)
		_node.Volumes = value
	}
	if value, ok := cc.mutation.WorkingDir(); ok {
		_spec.SetField(container.FieldWorkingDir, field.TypeString, value)
		_node.WorkingDir = value
	}
	if value, ok := cc.mutation.Entrypoint(); ok {
		_spec.SetField(container.FieldEntrypoint, field.TypeJSON, value)
		_node.Entrypoint = value
	}
	if value, ok := cc.mutation.MACAddress(); ok {
		_spec.SetField(container.FieldMACAddress, field.TypeString, value)
		_node.MACAddress = value
	}
	if value, ok := cc.mutation.ExposePorts(); ok {
		_spec.SetField(container.FieldExposePorts, field.TypeJSON, value)
		_node.ExposePorts = value
	}
	if value, ok := cc.mutation.ComposeFileURL(); ok {
		_spec.SetField(container.FieldComposeFileURL, field.TypeString, value)
		_node.ComposeFileURL = value
	}
	if value, ok := cc.mutation.DockerfileURL(); ok {
		_spec.SetField(container.FieldDockerfileURL, field.TypeString, value)
		_node.DockerfileURL = value
	}
	return _node, _spec
}

// ContainerCreateBulk is the builder for creating many Container entities in bulk.
type ContainerCreateBulk struct {
	config
	builders []*ContainerCreate
}

// Save creates the Container entities in the database.
func (ccb *ContainerCreateBulk) Save(ctx context.Context) ([]*Container, error) {
	specs := make([]*sqlgraph.CreateSpec, len(ccb.builders))
	nodes := make([]*Container, len(ccb.builders))
	mutators := make([]Mutator, len(ccb.builders))
	for i := range ccb.builders {
		func(i int, root context.Context) {
			builder := ccb.builders[i]
			var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
				mutation, ok := m.(*ContainerMutation)
				if !ok {
					return nil, fmt.Errorf("unexpected mutation type %T", m)
				}
				if err := builder.check(); err != nil {
					return nil, err
				}
				builder.mutation = mutation
				nodes[i], specs[i] = builder.createSpec()
				var err error
				if i < len(mutators)-1 {
					_, err = mutators[i+1].Mutate(root, ccb.builders[i+1].mutation)
				} else {
					spec := &sqlgraph.BatchCreateSpec{Nodes: specs}
					// Invoke the actual operation on the latest mutation in the chain.
					if err = sqlgraph.BatchCreate(ctx, ccb.driver, spec); err != nil {
						if sqlgraph.IsConstraintError(err) {
							err = &ConstraintError{msg: err.Error(), wrap: err}
						}
					}
				}
				if err != nil {
					return nil, err
				}
				mutation.id = &nodes[i].ID
				mutation.done = true
				return nodes[i], nil
			})
			for i := len(builder.hooks) - 1; i >= 0; i-- {
				mut = builder.hooks[i](mut)
			}
			mutators[i] = mut
		}(i, ctx)
	}
	if len(mutators) > 0 {
		if _, err := mutators[0].Mutate(ctx, ccb.builders[0].mutation); err != nil {
			return nil, err
		}
	}
	return nodes, nil
}

// SaveX is like Save, but panics if an error occurs.
func (ccb *ContainerCreateBulk) SaveX(ctx context.Context) []*Container {
	v, err := ccb.Save(ctx)
	if err != nil {
		panic(err)
	}
	return v
}

// Exec executes the query.
func (ccb *ContainerCreateBulk) Exec(ctx context.Context) error {
	_, err := ccb.Save(ctx)
	return err
}

// ExecX is like Exec, but panics if an error occurs.
func (ccb *ContainerCreateBulk) ExecX(ctx context.Context) {
	if err := ccb.Exec(ctx); err != nil {
		panic(err)
	}
}
