// Code generated by dagger. DO NOT EDIT.

package main

import (
	"context"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"os"
	"reflect"
	"strconv"

	"github.com/Khan/genqlient/graphql"

	"main/querybuilder"
)

// assertNotNil panic if the given value is nil.
// This function is used to validate that input with pointer type are not nil.
// See https://github.com/dagger/dagger/issues/5696 for more context.
func assertNotNil(argName string, value any) {
	// We use reflect because just comparing value to nil is not working since
	// the value is wrapped into a type when passed as parameter.
	// E.g., nil become (*dagger.File)(nil).
	if reflect.ValueOf(value).IsNil() {
		panic(fmt.Sprintf("unexpected nil pointer for argument %q", argName))
	}
}

// ptr returns a pointer to the given value.
func ptr[T any](v T) *T {
	return &v
}

// Optional is a helper type to represent optional values. Any method arguments
// that use this wrapper type will be set as optional in the generated API.
//
// To construct an Optional from within a module, use the Opt helper function.
type Optional[T comparable] struct {
	value T
	isSet bool
}

// Opt is a helper function to construct an Optional with the given value set.
func Opt[T comparable](v T) Optional[T] {
	return Optional[T]{value: v, isSet: true}
}

// Get returns the internal value of the optional and a boolean indicating if
// the value was set explicitly by the caller.
func (o Optional[T]) Get() (T, bool) {
	var zero T
	return o.value, o.isSet || o.value != zero
}

// GetOr returns the internal value of the optional or the given default value
// if the value was not explicitly set by the caller.
func (o Optional[T]) GetOr(defaultValue T) T {
	value, ok := o.Get()
	if !ok {
		return defaultValue
	}
	return value
}

func (o *Optional[T]) MarshalJSON() ([]byte, error) {
	return json.Marshal(&o.value)
}

func (o *Optional[T]) UnmarshalJSON(dt []byte) error {
	o.isSet = true
	return json.Unmarshal(dt, &o.value)
}

// A global cache volume identifier.
type CacheVolumeID string

// A unique container identifier. Null designates an empty container (scratch).
type ContainerID string

// A content-addressed directory identifier.
type DirectoryID string

// A file identifier.
type FileID string

// A reference to a FunctionArg.
type FunctionArgID string

// A reference to a Function.
type FunctionID string

// A reference to GeneratedCode.
type GeneratedCodeID string

// An arbitrary JSON-encoded value.
type JSON string

// A reference to a Module.
type ModuleID string

// The platform config OS and architecture in a Container.
//
// The format is [os]/[platform]/[version] (e.g., "darwin/arm64/v7", "windows/amd64", "linux/arm64").
type Platform string

// A unique identifier for a secret.
type SecretID string

// A unique service identifier.
type ServiceID string

// A content-addressed socket identifier.
type SocketID string

// A reference to a TypeDef.
type TypeDefID string

// The absense of a value.
//
// A Null Void is used as a placeholder for resolvers that do not return anything.
type Void string

// Key value object that represents a build argument.
type BuildArg struct {
	// The build argument name.
	Name string `json:"name"`

	// The build argument value.
	Value string `json:"value"`
}

// Key value object that represents a Pipeline label.
type PipelineLabel struct {
	// Label name.
	Name string `json:"name"`

	// Label value.
	Value string `json:"value"`
}

// Port forwarding rules for tunneling network traffic.
type PortForward struct {
	// Destination port for traffic.
	Backend int `json:"backend"`

	// Port to expose to clients. If unspecified, a default will be chosen.
	Frontend int `json:"frontend"`

	// Protocol to use for traffic.
	Protocol NetworkProtocol `json:"protocol,omitempty"`
}

// A directory whose contents persist across runs.
type CacheVolume struct {
	q *querybuilder.Selection
	c graphql.Client

	id *CacheVolumeID
}

func (r *CacheVolume) ID(ctx context.Context) (CacheVolumeID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response CacheVolumeID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *CacheVolume) XXX_GraphQLType() string {
	return "CacheVolume"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *CacheVolume) XXX_GraphQLIDType() string {
	return "CacheVolumeID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *CacheVolume) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *CacheVolume) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *CacheVolume) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadCacheVolumeFromID(CacheVolumeID(id))
	return nil
}

// An OCI-compatible container, also known as a docker container.
type Container struct {
	q *querybuilder.Selection
	c graphql.Client

	envVariable   *string
	export        *bool
	id            *ContainerID
	imageRef      *string
	label         *string
	platform      *Platform
	publish       *string
	shellEndpoint *string
	stderr        *string
	stdout        *string
	sync          *ContainerID
	user          *string
	workdir       *string
}
type WithContainerFunc func(r *Container) *Container

// With calls the provided function with current Container.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Container) With(f WithContainerFunc) *Container {
	return f(r)
}

// Turn the container into a Service.
//
// Be sure to set any exposed ports before this conversion.
func (r *Container) AsService() *Service {
	q := r.q.Select("asService")

	return &Service{
		q: q,
		c: r.c,
	}
}

// ContainerAsTarballOpts contains options for Container.AsTarball
type ContainerAsTarballOpts struct {
	// Identifiers for other platform specific containers.
	// Used for multi-platform image.
	PlatformVariants []*Container
	// Force each layer of the image to use the specified compression algorithm.
	// If this is unset, then if a layer already has a compressed blob in the engine's
	// cache, that will be used (this can result in a mix of compression algorithms for
	// different layers). If this is unset and a layer has no compressed blob in the
	// engine's cache, then it will be compressed using Gzip.
	ForcedCompression ImageLayerCompression
	// Use the specified media types for the image's layers. Defaults to OCI, which
	// is largely compatible with most recent container runtimes, but Docker may be needed
	// for older runtimes without OCI support.
	MediaTypes ImageMediaTypes
}

// Returns a File representing the container serialized to a tarball.
func (r *Container) AsTarball(opts ...ContainerAsTarballOpts) *File {
	q := r.q.Select("asTarball")
	for i := len(opts) - 1; i >= 0; i-- {
		// `platformVariants` optional argument
		if !querybuilder.IsZeroValue(opts[i].PlatformVariants) {
			q = q.Arg("platformVariants", opts[i].PlatformVariants)
		}
		// `forcedCompression` optional argument
		if !querybuilder.IsZeroValue(opts[i].ForcedCompression) {
			q = q.Arg("forcedCompression", opts[i].ForcedCompression)
		}
		// `mediaTypes` optional argument
		if !querybuilder.IsZeroValue(opts[i].MediaTypes) {
			q = q.Arg("mediaTypes", opts[i].MediaTypes)
		}
	}

	return &File{
		q: q,
		c: r.c,
	}
}

// ContainerBuildOpts contains options for Container.Build
type ContainerBuildOpts struct {
	// Path to the Dockerfile to use.
	//
	// Default: './Dockerfile'.
	Dockerfile string
	// Additional build arguments.
	BuildArgs []BuildArg
	// Target build stage to build.
	Target string
	// Secrets to pass to the build.
	//
	// They will be mounted at /run/secrets/[secret-name] in the build container
	//
	// They can be accessed in the Dockerfile using the "secret" mount type
	// and mount path /run/secrets/[secret-name]
	// e.g. RUN --mount=type=secret,id=my-secret curl url?token=$(cat /run/secrets/my-secret)"
	Secrets []*Secret
}

// Initializes this container from a Dockerfile build.
func (r *Container) Build(context *Directory, opts ...ContainerBuildOpts) *Container {
	assertNotNil("context", context)
	q := r.q.Select("build")
	for i := len(opts) - 1; i >= 0; i-- {
		// `dockerfile` optional argument
		if !querybuilder.IsZeroValue(opts[i].Dockerfile) {
			q = q.Arg("dockerfile", opts[i].Dockerfile)
		}
		// `buildArgs` optional argument
		if !querybuilder.IsZeroValue(opts[i].BuildArgs) {
			q = q.Arg("buildArgs", opts[i].BuildArgs)
		}
		// `target` optional argument
		if !querybuilder.IsZeroValue(opts[i].Target) {
			q = q.Arg("target", opts[i].Target)
		}
		// `secrets` optional argument
		if !querybuilder.IsZeroValue(opts[i].Secrets) {
			q = q.Arg("secrets", opts[i].Secrets)
		}
	}
	q = q.Arg("context", context)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves default arguments for future commands.
func (r *Container) DefaultArgs(ctx context.Context) ([]string, error) {
	q := r.q.Select("defaultArgs")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves a directory at the given path.
//
// Mounts are included.
func (r *Container) Directory(path string) *Directory {
	q := r.q.Select("directory")
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Retrieves entrypoint to be prepended to the arguments of all commands.
func (r *Container) Entrypoint(ctx context.Context) ([]string, error) {
	q := r.q.Select("entrypoint")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves the value of the specified environment variable.
func (r *Container) EnvVariable(ctx context.Context, name string) (string, error) {
	if r.envVariable != nil {
		return *r.envVariable, nil
	}
	q := r.q.Select("envVariable")
	q = q.Arg("name", name)

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves the list of environment variables passed to commands.
func (r *Container) EnvVariables(ctx context.Context) ([]EnvVariable, error) {
	q := r.q.Select("envVariables")

	q = q.Select("name value")

	type envVariables struct {
		Name  string
		Value string
	}

	convert := func(fields []envVariables) []EnvVariable {
		out := []EnvVariable{}

		for i := range fields {
			val := EnvVariable{name: &fields[i].Name, value: &fields[i].Value}
			out = append(out, val)
		}

		return out
	}
	var response []envVariables

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// EXPERIMENTAL API! Subject to change/removal at any time.
//
// experimentalWithAllGPUs configures all available GPUs on the host to be accessible to this container.
// This currently works for Nvidia devices only.
func (r *Container) ExperimentalWithAllGPUs() *Container {
	q := r.q.Select("experimentalWithAllGPUs")

	return &Container{
		q: q,
		c: r.c,
	}
}

// EXPERIMENTAL API! Subject to change/removal at any time.
//
// experimentalWithGPU configures the provided list of devices to be accesible to this container.
// This currently works for Nvidia devices only.
func (r *Container) ExperimentalWithGPU(devices []string) *Container {
	q := r.q.Select("experimentalWithGPU")
	q = q.Arg("devices", devices)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerExportOpts contains options for Container.Export
type ContainerExportOpts struct {
	// Identifiers for other platform specific containers.
	// Used for multi-platform image.
	PlatformVariants []*Container
	// Force each layer of the exported image to use the specified compression algorithm.
	// If this is unset, then if a layer already has a compressed blob in the engine's
	// cache, that will be used (this can result in a mix of compression algorithms for
	// different layers). If this is unset and a layer has no compressed blob in the
	// engine's cache, then it will be compressed using Gzip.
	ForcedCompression ImageLayerCompression
	// Use the specified media types for the exported image's layers. Defaults to OCI, which
	// is largely compatible with most recent container runtimes, but Docker may be needed
	// for older runtimes without OCI support.
	MediaTypes ImageMediaTypes
}

// Writes the container as an OCI tarball to the destination file path on the host for the specified platform variants.
//
// Return true on success.
// It can also publishes platform variants.
func (r *Container) Export(ctx context.Context, path string, opts ...ContainerExportOpts) (bool, error) {
	if r.export != nil {
		return *r.export, nil
	}
	q := r.q.Select("export")
	for i := len(opts) - 1; i >= 0; i-- {
		// `platformVariants` optional argument
		if !querybuilder.IsZeroValue(opts[i].PlatformVariants) {
			q = q.Arg("platformVariants", opts[i].PlatformVariants)
		}
		// `forcedCompression` optional argument
		if !querybuilder.IsZeroValue(opts[i].ForcedCompression) {
			q = q.Arg("forcedCompression", opts[i].ForcedCompression)
		}
		// `mediaTypes` optional argument
		if !querybuilder.IsZeroValue(opts[i].MediaTypes) {
			q = q.Arg("mediaTypes", opts[i].MediaTypes)
		}
	}
	q = q.Arg("path", path)

	var response bool

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves the list of exposed ports.
//
// This includes ports already exposed by the image, even if not
// explicitly added with dagger.
func (r *Container) ExposedPorts(ctx context.Context) ([]Port, error) {
	q := r.q.Select("exposedPorts")

	q = q.Select("description port protocol")

	type exposedPorts struct {
		Description string
		Port        int
		Protocol    NetworkProtocol
	}

	convert := func(fields []exposedPorts) []Port {
		out := []Port{}

		for i := range fields {
			val := Port{description: &fields[i].Description, port: &fields[i].Port, protocol: &fields[i].Protocol}
			out = append(out, val)
		}

		return out
	}
	var response []exposedPorts

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// Retrieves a file at the given path.
//
// Mounts are included.
func (r *Container) File(path string) *File {
	q := r.q.Select("file")
	q = q.Arg("path", path)

	return &File{
		q: q,
		c: r.c,
	}
}

// Initializes this container from a pulled base image.
func (r *Container) From(address string) *Container {
	q := r.q.Select("from")
	q = q.Arg("address", address)

	return &Container{
		q: q,
		c: r.c,
	}
}

// A unique identifier for this container.
func (r *Container) ID(ctx context.Context) (ContainerID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response ContainerID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Container) XXX_GraphQLType() string {
	return "Container"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Container) XXX_GraphQLIDType() string {
	return "ContainerID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Container) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Container) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Container) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadContainerFromID(ContainerID(id))
	return nil
}

// The unique image reference which can only be retrieved immediately after the 'Container.From' call.
func (r *Container) ImageRef(ctx context.Context) (string, error) {
	if r.imageRef != nil {
		return *r.imageRef, nil
	}
	q := r.q.Select("imageRef")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// ContainerImportOpts contains options for Container.Import
type ContainerImportOpts struct {
	// Identifies the tag to import from the archive, if the archive bundles
	// multiple tags.
	Tag string
}

// Reads the container from an OCI tarball.
//
// NOTE: this involves unpacking the tarball to an OCI store on the host at
// $XDG_CACHE_DIR/dagger/oci. This directory can be removed whenever you like.
func (r *Container) Import(source *File, opts ...ContainerImportOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("import")
	for i := len(opts) - 1; i >= 0; i-- {
		// `tag` optional argument
		if !querybuilder.IsZeroValue(opts[i].Tag) {
			q = q.Arg("tag", opts[i].Tag)
		}
	}
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves the value of the specified label.
func (r *Container) Label(ctx context.Context, name string) (string, error) {
	if r.label != nil {
		return *r.label, nil
	}
	q := r.q.Select("label")
	q = q.Arg("name", name)

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves the list of labels passed to container.
func (r *Container) Labels(ctx context.Context) ([]Label, error) {
	q := r.q.Select("labels")

	q = q.Select("name value")

	type labels struct {
		Name  string
		Value string
	}

	convert := func(fields []labels) []Label {
		out := []Label{}

		for i := range fields {
			val := Label{name: &fields[i].Name, value: &fields[i].Value}
			out = append(out, val)
		}

		return out
	}
	var response []labels

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// Retrieves the list of paths where a directory is mounted.
func (r *Container) Mounts(ctx context.Context) ([]string, error) {
	q := r.q.Select("mounts")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// ContainerPipelineOpts contains options for Container.Pipeline
type ContainerPipelineOpts struct {
	// Pipeline description.
	Description string
	// Pipeline labels.
	Labels []PipelineLabel
}

// Creates a named sub-pipeline
func (r *Container) Pipeline(name string, opts ...ContainerPipelineOpts) *Container {
	q := r.q.Select("pipeline")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
		// `labels` optional argument
		if !querybuilder.IsZeroValue(opts[i].Labels) {
			q = q.Arg("labels", opts[i].Labels)
		}
	}
	q = q.Arg("name", name)

	return &Container{
		q: q,
		c: r.c,
	}
}

// The platform this container executes and publishes as.
func (r *Container) Platform(ctx context.Context) (Platform, error) {
	if r.platform != nil {
		return *r.platform, nil
	}
	q := r.q.Select("platform")

	var response Platform

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// ContainerPublishOpts contains options for Container.Publish
type ContainerPublishOpts struct {
	// Identifiers for other platform specific containers.
	// Used for multi-platform image.
	PlatformVariants []*Container
	// Force each layer of the published image to use the specified compression algorithm.
	// If this is unset, then if a layer already has a compressed blob in the engine's
	// cache, that will be used (this can result in a mix of compression algorithms for
	// different layers). If this is unset and a layer has no compressed blob in the
	// engine's cache, then it will be compressed using Gzip.
	ForcedCompression ImageLayerCompression
	// Use the specified media types for the published image's layers. Defaults to OCI, which
	// is largely compatible with most recent registries, but Docker may be needed for older
	// registries without OCI support.
	MediaTypes ImageMediaTypes
}

// Publishes this container as a new image to the specified address.
//
// Publish returns a fully qualified ref.
// It can also publish platform variants.
func (r *Container) Publish(ctx context.Context, address string, opts ...ContainerPublishOpts) (string, error) {
	if r.publish != nil {
		return *r.publish, nil
	}
	q := r.q.Select("publish")
	for i := len(opts) - 1; i >= 0; i-- {
		// `platformVariants` optional argument
		if !querybuilder.IsZeroValue(opts[i].PlatformVariants) {
			q = q.Arg("platformVariants", opts[i].PlatformVariants)
		}
		// `forcedCompression` optional argument
		if !querybuilder.IsZeroValue(opts[i].ForcedCompression) {
			q = q.Arg("forcedCompression", opts[i].ForcedCompression)
		}
		// `mediaTypes` optional argument
		if !querybuilder.IsZeroValue(opts[i].MediaTypes) {
			q = q.Arg("mediaTypes", opts[i].MediaTypes)
		}
	}
	q = q.Arg("address", address)

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves this container's root filesystem. Mounts are not included.
func (r *Container) Rootfs() *Directory {
	q := r.q.Select("rootfs")

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Return a websocket endpoint that, if connected to, will start the container with a TTY streamed
// over the websocket.
//
// Primarily intended for internal use with the dagger CLI.
func (r *Container) ShellEndpoint(ctx context.Context) (string, error) {
	if r.shellEndpoint != nil {
		return *r.shellEndpoint, nil
	}
	q := r.q.Select("shellEndpoint")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The error stream of the last executed command.
//
// Will execute default command if none is set, or error if there's no default.
func (r *Container) Stderr(ctx context.Context) (string, error) {
	if r.stderr != nil {
		return *r.stderr, nil
	}
	q := r.q.Select("stderr")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The output stream of the last executed command.
//
// Will execute default command if none is set, or error if there's no default.
func (r *Container) Stdout(ctx context.Context) (string, error) {
	if r.stdout != nil {
		return *r.stdout, nil
	}
	q := r.q.Select("stdout")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Forces evaluation of the pipeline in the engine.
//
// It doesn't run the default command if no exec has been set.
func (r *Container) Sync(ctx context.Context) (*Container, error) {
	q := r.q.Select("sync")

	return r, q.Execute(ctx, r.c)
}

// Retrieves the user to be set for all commands.
func (r *Container) User(ctx context.Context) (string, error) {
	if r.user != nil {
		return *r.user, nil
	}
	q := r.q.Select("user")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// ContainerWithDefaultArgsOpts contains options for Container.WithDefaultArgs
type ContainerWithDefaultArgsOpts struct {
	// Arguments to prepend to future executions (e.g., ["-v", "--no-cache"]).
	Args []string
}

// Configures default arguments for future commands.
func (r *Container) WithDefaultArgs(opts ...ContainerWithDefaultArgsOpts) *Container {
	q := r.q.Select("withDefaultArgs")
	for i := len(opts) - 1; i >= 0; i-- {
		// `args` optional argument
		if !querybuilder.IsZeroValue(opts[i].Args) {
			q = q.Arg("args", opts[i].Args)
		}
	}

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithDirectoryOpts contains options for Container.WithDirectory
type ContainerWithDirectoryOpts struct {
	// Patterns to exclude in the written directory (e.g., ["node_modules/**", ".gitignore", ".git/"]).
	Exclude []string
	// Patterns to include in the written directory (e.g., ["*.go", "go.mod", "go.sum"]).
	Include []string
	// A user:group to set for the directory and its contents.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a directory written at the given path.
func (r *Container) WithDirectory(path string, directory *Directory, opts ...ContainerWithDirectoryOpts) *Container {
	assertNotNil("directory", directory)
	q := r.q.Select("withDirectory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `exclude` optional argument
		if !querybuilder.IsZeroValue(opts[i].Exclude) {
			q = q.Arg("exclude", opts[i].Exclude)
		}
		// `include` optional argument
		if !querybuilder.IsZeroValue(opts[i].Include) {
			q = q.Arg("include", opts[i].Include)
		}
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("directory", directory)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container but with a different command entrypoint.
func (r *Container) WithEntrypoint(args []string) *Container {
	q := r.q.Select("withEntrypoint")
	q = q.Arg("args", args)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithEnvVariableOpts contains options for Container.WithEnvVariable
type ContainerWithEnvVariableOpts struct {
	// Replace ${VAR} or $VAR in the value according to the current environment
	// variables defined in the container (e.g., "/opt/bin:$PATH").
	Expand bool
}

// Retrieves this container plus the given environment variable.
func (r *Container) WithEnvVariable(name string, value string, opts ...ContainerWithEnvVariableOpts) *Container {
	q := r.q.Select("withEnvVariable")
	for i := len(opts) - 1; i >= 0; i-- {
		// `expand` optional argument
		if !querybuilder.IsZeroValue(opts[i].Expand) {
			q = q.Arg("expand", opts[i].Expand)
		}
	}
	q = q.Arg("name", name)
	q = q.Arg("value", value)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithExecOpts contains options for Container.WithExec
type ContainerWithExecOpts struct {
	// If the container has an entrypoint, ignore it for args rather than using it to wrap them.
	SkipEntrypoint bool
	// Content to write to the command's standard input before closing (e.g., "Hello world").
	Stdin string
	// Redirect the command's standard output to a file in the container (e.g., "/tmp/stdout").
	RedirectStdout string
	// Redirect the command's standard error to a file in the container (e.g., "/tmp/stderr").
	RedirectStderr string
	// Provides dagger access to the executed command.
	//
	// Do not use this option unless you trust the command being executed.
	// The command being executed WILL BE GRANTED FULL ACCESS TO YOUR HOST FILESYSTEM.
	ExperimentalPrivilegedNesting bool
	// Execute the command with all root capabilities. This is similar to running a command
	// with "sudo" or executing `docker run` with the `--privileged` flag. Containerization
	// does not provide any security guarantees when using this option. It should only be used
	// when absolutely necessary and only with trusted commands.
	InsecureRootCapabilities bool
}

// Retrieves this container after executing the specified command inside it.
func (r *Container) WithExec(args []string, opts ...ContainerWithExecOpts) *Container {
	q := r.q.Select("withExec")
	for i := len(opts) - 1; i >= 0; i-- {
		// `skipEntrypoint` optional argument
		if !querybuilder.IsZeroValue(opts[i].SkipEntrypoint) {
			q = q.Arg("skipEntrypoint", opts[i].SkipEntrypoint)
		}
		// `stdin` optional argument
		if !querybuilder.IsZeroValue(opts[i].Stdin) {
			q = q.Arg("stdin", opts[i].Stdin)
		}
		// `redirectStdout` optional argument
		if !querybuilder.IsZeroValue(opts[i].RedirectStdout) {
			q = q.Arg("redirectStdout", opts[i].RedirectStdout)
		}
		// `redirectStderr` optional argument
		if !querybuilder.IsZeroValue(opts[i].RedirectStderr) {
			q = q.Arg("redirectStderr", opts[i].RedirectStderr)
		}
		// `experimentalPrivilegedNesting` optional argument
		if !querybuilder.IsZeroValue(opts[i].ExperimentalPrivilegedNesting) {
			q = q.Arg("experimentalPrivilegedNesting", opts[i].ExperimentalPrivilegedNesting)
		}
		// `insecureRootCapabilities` optional argument
		if !querybuilder.IsZeroValue(opts[i].InsecureRootCapabilities) {
			q = q.Arg("insecureRootCapabilities", opts[i].InsecureRootCapabilities)
		}
	}
	q = q.Arg("args", args)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithExposedPortOpts contains options for Container.WithExposedPort
type ContainerWithExposedPortOpts struct {
	// Transport layer network protocol
	Protocol NetworkProtocol
	// Optional port description
	Description string
}

// Expose a network port.
//
// Exposed ports serve two purposes:
//   - For health checks and introspection, when running services
//   - For setting the EXPOSE OCI field when publishing the container
func (r *Container) WithExposedPort(port int, opts ...ContainerWithExposedPortOpts) *Container {
	q := r.q.Select("withExposedPort")
	for i := len(opts) - 1; i >= 0; i-- {
		// `protocol` optional argument
		if !querybuilder.IsZeroValue(opts[i].Protocol) {
			q = q.Arg("protocol", opts[i].Protocol)
		}
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
	}
	q = q.Arg("port", port)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithFileOpts contains options for Container.WithFile
type ContainerWithFileOpts struct {
	// Permission given to the copied file (e.g., 0600).
	//
	// Default: 0644.
	Permissions int
	// A user:group to set for the file.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus the contents of the given file copied to the given path.
func (r *Container) WithFile(path string, source *File, opts ...ContainerWithFileOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("withFile")
	for i := len(opts) - 1; i >= 0; i-- {
		// `permissions` optional argument
		if !querybuilder.IsZeroValue(opts[i].Permissions) {
			q = q.Arg("permissions", opts[i].Permissions)
		}
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Indicate that subsequent operations should be featured more prominently in
// the UI.
func (r *Container) WithFocus() *Container {
	q := r.q.Select("withFocus")

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container plus the given label.
func (r *Container) WithLabel(name string, value string) *Container {
	q := r.q.Select("withLabel")
	q = q.Arg("name", name)
	q = q.Arg("value", value)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithMountedCacheOpts contains options for Container.WithMountedCache
type ContainerWithMountedCacheOpts struct {
	// Identifier of the directory to use as the cache volume's root.
	Source *Directory
	// Sharing mode of the cache volume.
	Sharing CacheSharingMode
	// A user:group to set for the mounted cache directory.
	//
	// Note that this changes the ownership of the specified mount along with the
	// initial filesystem provided by source (if any). It does not have any effect
	// if/when the cache has already been created.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a cache volume mounted at the given path.
func (r *Container) WithMountedCache(path string, cache *CacheVolume, opts ...ContainerWithMountedCacheOpts) *Container {
	assertNotNil("cache", cache)
	q := r.q.Select("withMountedCache")
	for i := len(opts) - 1; i >= 0; i-- {
		// `source` optional argument
		if !querybuilder.IsZeroValue(opts[i].Source) {
			q = q.Arg("source", opts[i].Source)
		}
		// `sharing` optional argument
		if !querybuilder.IsZeroValue(opts[i].Sharing) {
			q = q.Arg("sharing", opts[i].Sharing)
		}
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("cache", cache)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithMountedDirectoryOpts contains options for Container.WithMountedDirectory
type ContainerWithMountedDirectoryOpts struct {
	// A user:group to set for the mounted directory and its contents.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a directory mounted at the given path.
func (r *Container) WithMountedDirectory(path string, source *Directory, opts ...ContainerWithMountedDirectoryOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("withMountedDirectory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithMountedFileOpts contains options for Container.WithMountedFile
type ContainerWithMountedFileOpts struct {
	// A user or user:group to set for the mounted file.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a file mounted at the given path.
func (r *Container) WithMountedFile(path string, source *File, opts ...ContainerWithMountedFileOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("withMountedFile")
	for i := len(opts) - 1; i >= 0; i-- {
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithMountedSecretOpts contains options for Container.WithMountedSecret
type ContainerWithMountedSecretOpts struct {
	// A user:group to set for the mounted secret.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
	// Permission given to the mounted secret (e.g., 0600).
	// This option requires an owner to be set to be active.
	//
	// Default: 0400.
	Mode int
}

// Retrieves this container plus a secret mounted into a file at the given path.
func (r *Container) WithMountedSecret(path string, source *Secret, opts ...ContainerWithMountedSecretOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("withMountedSecret")
	for i := len(opts) - 1; i >= 0; i-- {
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
		// `mode` optional argument
		if !querybuilder.IsZeroValue(opts[i].Mode) {
			q = q.Arg("mode", opts[i].Mode)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container plus a temporary directory mounted at the given path.
func (r *Container) WithMountedTemp(path string) *Container {
	q := r.q.Select("withMountedTemp")
	q = q.Arg("path", path)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithNewFileOpts contains options for Container.WithNewFile
type ContainerWithNewFileOpts struct {
	// Content of the file to write (e.g., "Hello world!").
	Contents string
	// Permission given to the written file (e.g., 0600).
	//
	// Default: 0644.
	Permissions int
	// A user:group to set for the file.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a new file written at the given path.
func (r *Container) WithNewFile(path string, opts ...ContainerWithNewFileOpts) *Container {
	q := r.q.Select("withNewFile")
	for i := len(opts) - 1; i >= 0; i-- {
		// `contents` optional argument
		if !querybuilder.IsZeroValue(opts[i].Contents) {
			q = q.Arg("contents", opts[i].Contents)
		}
		// `permissions` optional argument
		if !querybuilder.IsZeroValue(opts[i].Permissions) {
			q = q.Arg("permissions", opts[i].Permissions)
		}
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container with a registry authentication for a given address.
func (r *Container) WithRegistryAuth(address string, username string, secret *Secret) *Container {
	assertNotNil("secret", secret)
	q := r.q.Select("withRegistryAuth")
	q = q.Arg("address", address)
	q = q.Arg("username", username)
	q = q.Arg("secret", secret)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Initializes this container from this DirectoryID.
func (r *Container) WithRootfs(directory *Directory) *Container {
	assertNotNil("directory", directory)
	q := r.q.Select("withRootfs")
	q = q.Arg("directory", directory)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container plus an env variable containing the given secret.
func (r *Container) WithSecretVariable(name string, secret *Secret) *Container {
	assertNotNil("secret", secret)
	q := r.q.Select("withSecretVariable")
	q = q.Arg("name", name)
	q = q.Arg("secret", secret)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Establish a runtime dependency on a service.
//
// The service will be started automatically when needed and detached when it is
// no longer needed, executing the default command if none is set.
//
// The service will be reachable from the container via the provided hostname alias.
//
// The service dependency will also convey to any files or directories produced by the container.
func (r *Container) WithServiceBinding(alias string, service *Service) *Container {
	assertNotNil("service", service)
	q := r.q.Select("withServiceBinding")
	q = q.Arg("alias", alias)
	q = q.Arg("service", service)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithUnixSocketOpts contains options for Container.WithUnixSocket
type ContainerWithUnixSocketOpts struct {
	// A user:group to set for the mounted socket.
	//
	// The user and group can either be an ID (1000:1000) or a name (foo:bar).
	//
	// If the group is omitted, it defaults to the same as the user.
	Owner string
}

// Retrieves this container plus a socket forwarded to the given Unix socket path.
func (r *Container) WithUnixSocket(path string, source *Socket, opts ...ContainerWithUnixSocketOpts) *Container {
	assertNotNil("source", source)
	q := r.q.Select("withUnixSocket")
	for i := len(opts) - 1; i >= 0; i-- {
		// `owner` optional argument
		if !querybuilder.IsZeroValue(opts[i].Owner) {
			q = q.Arg("owner", opts[i].Owner)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container with a different command user.
func (r *Container) WithUser(name string) *Container {
	q := r.q.Select("withUser")
	q = q.Arg("name", name)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container with a different working directory.
func (r *Container) WithWorkdir(path string) *Container {
	q := r.q.Select("withWorkdir")
	q = q.Arg("path", path)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container minus the given environment variable.
func (r *Container) WithoutEnvVariable(name string) *Container {
	q := r.q.Select("withoutEnvVariable")
	q = q.Arg("name", name)

	return &Container{
		q: q,
		c: r.c,
	}
}

// ContainerWithoutExposedPortOpts contains options for Container.WithoutExposedPort
type ContainerWithoutExposedPortOpts struct {
	// Port protocol to unexpose
	Protocol NetworkProtocol
}

// Unexpose a previously exposed port.
func (r *Container) WithoutExposedPort(port int, opts ...ContainerWithoutExposedPortOpts) *Container {
	q := r.q.Select("withoutExposedPort")
	for i := len(opts) - 1; i >= 0; i-- {
		// `protocol` optional argument
		if !querybuilder.IsZeroValue(opts[i].Protocol) {
			q = q.Arg("protocol", opts[i].Protocol)
		}
	}
	q = q.Arg("port", port)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Indicate that subsequent operations should not be featured more prominently
// in the UI.
//
// This is the initial state of all containers.
func (r *Container) WithoutFocus() *Container {
	q := r.q.Select("withoutFocus")

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container minus the given environment label.
func (r *Container) WithoutLabel(name string) *Container {
	q := r.q.Select("withoutLabel")
	q = q.Arg("name", name)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container after unmounting everything at the given path.
func (r *Container) WithoutMount(path string) *Container {
	q := r.q.Select("withoutMount")
	q = q.Arg("path", path)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container without the registry authentication of a given address.
func (r *Container) WithoutRegistryAuth(address string) *Container {
	q := r.q.Select("withoutRegistryAuth")
	q = q.Arg("address", address)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves this container with a previously added Unix socket removed.
func (r *Container) WithoutUnixSocket(path string) *Container {
	q := r.q.Select("withoutUnixSocket")
	q = q.Arg("path", path)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Retrieves the working directory for all commands.
func (r *Container) Workdir(ctx context.Context) (string, error) {
	if r.workdir != nil {
		return *r.workdir, nil
	}
	q := r.q.Select("workdir")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A directory.
type Directory struct {
	q *querybuilder.Selection
	c graphql.Client

	export *bool
	id     *DirectoryID
	sync   *DirectoryID
}
type WithDirectoryFunc func(r *Directory) *Directory

// With calls the provided function with current Directory.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Directory) With(f WithDirectoryFunc) *Directory {
	return f(r)
}

// DirectoryAsModuleOpts contains options for Directory.AsModule
type DirectoryAsModuleOpts struct {
	// An optional subpath of the directory which contains the module's source
	// code.
	//
	// This is needed when the module code is in a subdirectory but requires
	// parent directories to be loaded in order to execute. For example, the
	// module source code may need a go.mod, project.toml, package.json, etc. file
	// from a parent directory.
	//
	// If not set, the module source code is loaded from the root of the
	// directory.
	SourceSubpath string
}

// Load the directory as a Dagger module
func (r *Directory) AsModule(opts ...DirectoryAsModuleOpts) *Module {
	q := r.q.Select("asModule")
	for i := len(opts) - 1; i >= 0; i-- {
		// `sourceSubpath` optional argument
		if !querybuilder.IsZeroValue(opts[i].SourceSubpath) {
			q = q.Arg("sourceSubpath", opts[i].SourceSubpath)
		}
	}

	return &Module{
		q: q,
		c: r.c,
	}
}

// Gets the difference between this directory and an another directory.
func (r *Directory) Diff(other *Directory) *Directory {
	assertNotNil("other", other)
	q := r.q.Select("diff")
	q = q.Arg("other", other)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Retrieves a directory at the given path.
func (r *Directory) Directory(path string) *Directory {
	q := r.q.Select("directory")
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// DirectoryDockerBuildOpts contains options for Directory.DockerBuild
type DirectoryDockerBuildOpts struct {
	// Path to the Dockerfile to use (e.g., "frontend.Dockerfile").
	//
	// Defaults: './Dockerfile'.
	Dockerfile string
	// The platform to build.
	Platform Platform
	// Build arguments to use in the build.
	BuildArgs []BuildArg
	// Target build stage to build.
	Target string
	// Secrets to pass to the build.
	//
	// They will be mounted at /run/secrets/[secret-name].
	Secrets []*Secret
}

// Builds a new Docker container from this directory.
func (r *Directory) DockerBuild(opts ...DirectoryDockerBuildOpts) *Container {
	q := r.q.Select("dockerBuild")
	for i := len(opts) - 1; i >= 0; i-- {
		// `dockerfile` optional argument
		if !querybuilder.IsZeroValue(opts[i].Dockerfile) {
			q = q.Arg("dockerfile", opts[i].Dockerfile)
		}
		// `platform` optional argument
		if !querybuilder.IsZeroValue(opts[i].Platform) {
			q = q.Arg("platform", opts[i].Platform)
		}
		// `buildArgs` optional argument
		if !querybuilder.IsZeroValue(opts[i].BuildArgs) {
			q = q.Arg("buildArgs", opts[i].BuildArgs)
		}
		// `target` optional argument
		if !querybuilder.IsZeroValue(opts[i].Target) {
			q = q.Arg("target", opts[i].Target)
		}
		// `secrets` optional argument
		if !querybuilder.IsZeroValue(opts[i].Secrets) {
			q = q.Arg("secrets", opts[i].Secrets)
		}
	}

	return &Container{
		q: q,
		c: r.c,
	}
}

// DirectoryEntriesOpts contains options for Directory.Entries
type DirectoryEntriesOpts struct {
	// Location of the directory to look at (e.g., "/src").
	Path string
}

// Returns a list of files and directories at the given path.
func (r *Directory) Entries(ctx context.Context, opts ...DirectoryEntriesOpts) ([]string, error) {
	q := r.q.Select("entries")
	for i := len(opts) - 1; i >= 0; i-- {
		// `path` optional argument
		if !querybuilder.IsZeroValue(opts[i].Path) {
			q = q.Arg("path", opts[i].Path)
		}
	}

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Writes the contents of the directory to a path on the host.
func (r *Directory) Export(ctx context.Context, path string) (bool, error) {
	if r.export != nil {
		return *r.export, nil
	}
	q := r.q.Select("export")
	q = q.Arg("path", path)

	var response bool

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves a file at the given path.
func (r *Directory) File(path string) *File {
	q := r.q.Select("file")
	q = q.Arg("path", path)

	return &File{
		q: q,
		c: r.c,
	}
}

// Returns a list of files and directories that matche the given pattern.
func (r *Directory) Glob(ctx context.Context, pattern string) ([]string, error) {
	q := r.q.Select("glob")
	q = q.Arg("pattern", pattern)

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The content-addressed identifier of the directory.
func (r *Directory) ID(ctx context.Context) (DirectoryID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response DirectoryID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Directory) XXX_GraphQLType() string {
	return "Directory"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Directory) XXX_GraphQLIDType() string {
	return "DirectoryID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Directory) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Directory) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Directory) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadDirectoryFromID(DirectoryID(id))
	return nil
}

// DirectoryPipelineOpts contains options for Directory.Pipeline
type DirectoryPipelineOpts struct {
	// Pipeline description.
	Description string
	// Pipeline labels.
	Labels []PipelineLabel
}

// Creates a named sub-pipeline
func (r *Directory) Pipeline(name string, opts ...DirectoryPipelineOpts) *Directory {
	q := r.q.Select("pipeline")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
		// `labels` optional argument
		if !querybuilder.IsZeroValue(opts[i].Labels) {
			q = q.Arg("labels", opts[i].Labels)
		}
	}
	q = q.Arg("name", name)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Force evaluation in the engine.
func (r *Directory) Sync(ctx context.Context) (*Directory, error) {
	q := r.q.Select("sync")

	return r, q.Execute(ctx, r.c)
}

// DirectoryWithDirectoryOpts contains options for Directory.WithDirectory
type DirectoryWithDirectoryOpts struct {
	// Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]).
	Exclude []string
	// Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]).
	Include []string
}

// Retrieves this directory plus a directory written at the given path.
func (r *Directory) WithDirectory(path string, directory *Directory, opts ...DirectoryWithDirectoryOpts) *Directory {
	assertNotNil("directory", directory)
	q := r.q.Select("withDirectory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `exclude` optional argument
		if !querybuilder.IsZeroValue(opts[i].Exclude) {
			q = q.Arg("exclude", opts[i].Exclude)
		}
		// `include` optional argument
		if !querybuilder.IsZeroValue(opts[i].Include) {
			q = q.Arg("include", opts[i].Include)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("directory", directory)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// DirectoryWithFileOpts contains options for Directory.WithFile
type DirectoryWithFileOpts struct {
	// Permission given to the copied file (e.g., 0600).
	//
	// Default: 0644.
	Permissions int
}

// Retrieves this directory plus the contents of the given file copied to the given path.
func (r *Directory) WithFile(path string, source *File, opts ...DirectoryWithFileOpts) *Directory {
	assertNotNil("source", source)
	q := r.q.Select("withFile")
	for i := len(opts) - 1; i >= 0; i-- {
		// `permissions` optional argument
		if !querybuilder.IsZeroValue(opts[i].Permissions) {
			q = q.Arg("permissions", opts[i].Permissions)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("source", source)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// DirectoryWithNewDirectoryOpts contains options for Directory.WithNewDirectory
type DirectoryWithNewDirectoryOpts struct {
	// Permission granted to the created directory (e.g., 0777).
	//
	// Default: 0755.
	Permissions int
}

// Retrieves this directory plus a new directory created at the given path.
func (r *Directory) WithNewDirectory(path string, opts ...DirectoryWithNewDirectoryOpts) *Directory {
	q := r.q.Select("withNewDirectory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `permissions` optional argument
		if !querybuilder.IsZeroValue(opts[i].Permissions) {
			q = q.Arg("permissions", opts[i].Permissions)
		}
	}
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// DirectoryWithNewFileOpts contains options for Directory.WithNewFile
type DirectoryWithNewFileOpts struct {
	// Permission given to the copied file (e.g., 0600).
	//
	// Default: 0644.
	Permissions int
}

// Retrieves this directory plus a new file written at the given path.
func (r *Directory) WithNewFile(path string, contents string, opts ...DirectoryWithNewFileOpts) *Directory {
	q := r.q.Select("withNewFile")
	for i := len(opts) - 1; i >= 0; i-- {
		// `permissions` optional argument
		if !querybuilder.IsZeroValue(opts[i].Permissions) {
			q = q.Arg("permissions", opts[i].Permissions)
		}
	}
	q = q.Arg("path", path)
	q = q.Arg("contents", contents)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Retrieves this directory with all file/dir timestamps set to the given time.
func (r *Directory) WithTimestamps(timestamp int) *Directory {
	q := r.q.Select("withTimestamps")
	q = q.Arg("timestamp", timestamp)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Retrieves this directory with the directory at the given path removed.
func (r *Directory) WithoutDirectory(path string) *Directory {
	q := r.q.Select("withoutDirectory")
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Retrieves this directory with the file at the given path removed.
func (r *Directory) WithoutFile(path string) *Directory {
	q := r.q.Select("withoutFile")
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// A simple key value object that represents an environment variable.
type EnvVariable struct {
	q *querybuilder.Selection
	c graphql.Client

	name  *string
	value *string
}

// The environment variable name.
func (r *EnvVariable) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The environment variable value.
func (r *EnvVariable) Value(ctx context.Context) (string, error) {
	if r.value != nil {
		return *r.value, nil
	}
	q := r.q.Select("value")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A definition of a field on a custom object defined in a Module.
// A field on an object has a static value, as opposed to a function on an
// object whose value is computed by invoking code (and can accept arguments).
type FieldTypeDef struct {
	q *querybuilder.Selection
	c graphql.Client

	description *string
	name        *string
}

// A doc string for the field, if any
func (r *FieldTypeDef) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The name of the field in the object
func (r *FieldTypeDef) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The type of the field
func (r *FieldTypeDef) TypeDef() *TypeDef {
	q := r.q.Select("typeDef")

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// A file.
type File struct {
	q *querybuilder.Selection
	c graphql.Client

	contents *string
	export   *bool
	id       *FileID
	size     *int
	sync     *FileID
}
type WithFileFunc func(r *File) *File

// With calls the provided function with current File.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *File) With(f WithFileFunc) *File {
	return f(r)
}

// Retrieves the contents of the file.
func (r *File) Contents(ctx context.Context) (string, error) {
	if r.contents != nil {
		return *r.contents, nil
	}
	q := r.q.Select("contents")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// FileExportOpts contains options for File.Export
type FileExportOpts struct {
	// If allowParentDirPath is true, the path argument can be a directory path, in which case
	// the file will be created in that directory.
	AllowParentDirPath bool
}

// Writes the file to a file path on the host.
func (r *File) Export(ctx context.Context, path string, opts ...FileExportOpts) (bool, error) {
	if r.export != nil {
		return *r.export, nil
	}
	q := r.q.Select("export")
	for i := len(opts) - 1; i >= 0; i-- {
		// `allowParentDirPath` optional argument
		if !querybuilder.IsZeroValue(opts[i].AllowParentDirPath) {
			q = q.Arg("allowParentDirPath", opts[i].AllowParentDirPath)
		}
	}
	q = q.Arg("path", path)

	var response bool

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves the content-addressed identifier of the file.
func (r *File) ID(ctx context.Context) (FileID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response FileID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *File) XXX_GraphQLType() string {
	return "File"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *File) XXX_GraphQLIDType() string {
	return "FileID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *File) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *File) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *File) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadFileFromID(FileID(id))
	return nil
}

// Gets the size of the file, in bytes.
func (r *File) Size(ctx context.Context) (int, error) {
	if r.size != nil {
		return *r.size, nil
	}
	q := r.q.Select("size")

	var response int

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Force evaluation in the engine.
func (r *File) Sync(ctx context.Context) (*File, error) {
	q := r.q.Select("sync")

	return r, q.Execute(ctx, r.c)
}

// Retrieves this file with its created/modified timestamps set to the given time.
func (r *File) WithTimestamps(timestamp int) *File {
	q := r.q.Select("withTimestamps")
	q = q.Arg("timestamp", timestamp)

	return &File{
		q: q,
		c: r.c,
	}
}

// Function represents a resolver provided by a Module.
//
// A function always evaluates against a parent object and is given a set of
// named arguments.
type Function struct {
	q *querybuilder.Selection
	c graphql.Client

	description *string
	id          *FunctionID
	name        *string
}
type WithFunctionFunc func(r *Function) *Function

// With calls the provided function with current Function.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Function) With(f WithFunctionFunc) *Function {
	return f(r)
}

// Arguments accepted by this function, if any
func (r *Function) Args(ctx context.Context) ([]FunctionArg, error) {
	q := r.q.Select("args")

	q = q.Select("id")

	type args struct {
		Id FunctionArgID
	}

	convert := func(fields []args) []FunctionArg {
		out := []FunctionArg{}

		for i := range fields {
			val := FunctionArg{id: &fields[i].Id}
			val.q = querybuilder.Query().Select("loadFunctionArgFromID").Arg("id", fields[i].Id)
			val.c = r.c
			out = append(out, val)
		}

		return out
	}
	var response []args

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// A doc string for the function, if any
func (r *Function) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The ID of the function
func (r *Function) ID(ctx context.Context) (FunctionID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response FunctionID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Function) XXX_GraphQLType() string {
	return "Function"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Function) XXX_GraphQLIDType() string {
	return "FunctionID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Function) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Function) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Function) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadFunctionFromID(FunctionID(id))
	return nil
}

// The name of the function
func (r *Function) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The type returned by this function
func (r *Function) ReturnType() *TypeDef {
	q := r.q.Select("returnType")

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// FunctionWithArgOpts contains options for Function.WithArg
type FunctionWithArgOpts struct {
	// A doc string for the argument, if any
	Description string
	// A default value to use for this argument if not explicitly set by the caller, if any
	DefaultValue JSON
}

// Returns the function with the provided argument
func (r *Function) WithArg(name string, typeDef *TypeDef, opts ...FunctionWithArgOpts) *Function {
	assertNotNil("typeDef", typeDef)
	q := r.q.Select("withArg")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
		// `defaultValue` optional argument
		if !querybuilder.IsZeroValue(opts[i].DefaultValue) {
			q = q.Arg("defaultValue", opts[i].DefaultValue)
		}
	}
	q = q.Arg("name", name)
	q = q.Arg("typeDef", typeDef)

	return &Function{
		q: q,
		c: r.c,
	}
}

// Returns the function with the doc string
func (r *Function) WithDescription(description string) *Function {
	q := r.q.Select("withDescription")
	q = q.Arg("description", description)

	return &Function{
		q: q,
		c: r.c,
	}
}

// An argument accepted by a function.
//
// This is a specification for an argument at function definition time, not an
// argument passed at function call time.
type FunctionArg struct {
	q *querybuilder.Selection
	c graphql.Client

	defaultValue *JSON
	description  *string
	id           *FunctionArgID
	name         *string
}

// A default value to use for this argument when not explicitly set by the caller, if any
func (r *FunctionArg) DefaultValue(ctx context.Context) (JSON, error) {
	if r.defaultValue != nil {
		return *r.defaultValue, nil
	}
	q := r.q.Select("defaultValue")

	var response JSON

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A doc string for the argument, if any
func (r *FunctionArg) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The ID of the argument
func (r *FunctionArg) ID(ctx context.Context) (FunctionArgID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response FunctionArgID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *FunctionArg) XXX_GraphQLType() string {
	return "FunctionArg"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *FunctionArg) XXX_GraphQLIDType() string {
	return "FunctionArgID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *FunctionArg) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *FunctionArg) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *FunctionArg) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadFunctionArgFromID(FunctionArgID(id))
	return nil
}

// The name of the argument
func (r *FunctionArg) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The type of the argument
func (r *FunctionArg) TypeDef() *TypeDef {
	q := r.q.Select("typeDef")

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

type FunctionCall struct {
	q *querybuilder.Selection
	c graphql.Client

	name        *string
	parent      *JSON
	parentName  *string
	returnValue *Void
}

// The argument values the function is being invoked with.
func (r *FunctionCall) InputArgs(ctx context.Context) ([]FunctionCallArgValue, error) {
	q := r.q.Select("inputArgs")

	q = q.Select("name value")

	type inputArgs struct {
		Name  string
		Value JSON
	}

	convert := func(fields []inputArgs) []FunctionCallArgValue {
		out := []FunctionCallArgValue{}

		for i := range fields {
			val := FunctionCallArgValue{name: &fields[i].Name, value: &fields[i].Value}
			out = append(out, val)
		}

		return out
	}
	var response []inputArgs

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// The name of the function being called.
func (r *FunctionCall) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The value of the parent object of the function being called.
// If the function is "top-level" to the module, this is always an empty object.
func (r *FunctionCall) Parent(ctx context.Context) (JSON, error) {
	if r.parent != nil {
		return *r.parent, nil
	}
	q := r.q.Select("parent")

	var response JSON

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The name of the parent object of the function being called.
// If the function is "top-level" to the module, this is the name of the module.
func (r *FunctionCall) ParentName(ctx context.Context) (string, error) {
	if r.parentName != nil {
		return *r.parentName, nil
	}
	q := r.q.Select("parentName")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Set the return value of the function call to the provided value.
// The value should be a string of the JSON serialization of the return value.
func (r *FunctionCall) ReturnValue(ctx context.Context, value JSON) (Void, error) {
	if r.returnValue != nil {
		return *r.returnValue, nil
	}
	q := r.q.Select("returnValue")
	q = q.Arg("value", value)

	var response Void

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

type FunctionCallArgValue struct {
	q *querybuilder.Selection
	c graphql.Client

	name  *string
	value *JSON
}

// The name of the argument.
func (r *FunctionCallArgValue) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The value of the argument represented as a string of the JSON serialization.
func (r *FunctionCallArgValue) Value(ctx context.Context) (JSON, error) {
	if r.value != nil {
		return *r.value, nil
	}
	q := r.q.Select("value")

	var response JSON

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

type GeneratedCode struct {
	q *querybuilder.Selection
	c graphql.Client

	id *GeneratedCodeID
}
type WithGeneratedCodeFunc func(r *GeneratedCode) *GeneratedCode

// With calls the provided function with current GeneratedCode.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *GeneratedCode) With(f WithGeneratedCodeFunc) *GeneratedCode {
	return f(r)
}

// The directory containing the generated code
func (r *GeneratedCode) Code() *Directory {
	q := r.q.Select("code")

	return &Directory{
		q: q,
		c: r.c,
	}
}

func (r *GeneratedCode) ID(ctx context.Context) (GeneratedCodeID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response GeneratedCodeID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *GeneratedCode) XXX_GraphQLType() string {
	return "GeneratedCode"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *GeneratedCode) XXX_GraphQLIDType() string {
	return "GeneratedCodeID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *GeneratedCode) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *GeneratedCode) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *GeneratedCode) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadGeneratedCodeFromID(GeneratedCodeID(id))
	return nil
}

// List of paths to mark generated in version control (i.e. .gitattributes)
func (r *GeneratedCode) VcsGeneratedPaths(ctx context.Context) ([]string, error) {
	q := r.q.Select("vcsGeneratedPaths")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// List of paths to ignore in version control (i.e. .gitignore)
func (r *GeneratedCode) VcsIgnoredPaths(ctx context.Context) ([]string, error) {
	q := r.q.Select("vcsIgnoredPaths")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Set the list of paths to mark generated in version control
func (r *GeneratedCode) WithVCSGeneratedPaths(paths []string) *GeneratedCode {
	q := r.q.Select("withVCSGeneratedPaths")
	q = q.Arg("paths", paths)

	return &GeneratedCode{
		q: q,
		c: r.c,
	}
}

// Set the list of paths to ignore in version control
func (r *GeneratedCode) WithVCSIgnoredPaths(paths []string) *GeneratedCode {
	q := r.q.Select("withVCSIgnoredPaths")
	q = q.Arg("paths", paths)

	return &GeneratedCode{
		q: q,
		c: r.c,
	}
}

// A git ref (tag, branch or commit).
type GitRef struct {
	q *querybuilder.Selection
	c graphql.Client

	commit *string
}

// The resolved commit id at this ref.
func (r *GitRef) Commit(ctx context.Context) (string, error) {
	if r.commit != nil {
		return *r.commit, nil
	}
	q := r.q.Select("commit")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// GitRefTreeOpts contains options for GitRef.Tree
type GitRefTreeOpts struct {
	SSHKnownHosts string

	SSHAuthSocket *Socket
}

// The filesystem tree at this ref.
func (r *GitRef) Tree(opts ...GitRefTreeOpts) *Directory {
	q := r.q.Select("tree")
	for i := len(opts) - 1; i >= 0; i-- {
		// `sshKnownHosts` optional argument
		if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) {
			q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts)
		}
		// `sshAuthSocket` optional argument
		if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) {
			q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket)
		}
	}

	return &Directory{
		q: q,
		c: r.c,
	}
}

// A git repository.
type GitRepository struct {
	q *querybuilder.Selection
	c graphql.Client
}

// Returns details on one branch.
func (r *GitRepository) Branch(name string) *GitRef {
	q := r.q.Select("branch")
	q = q.Arg("name", name)

	return &GitRef{
		q: q,
		c: r.c,
	}
}

// Returns details on one commit.
func (r *GitRepository) Commit(id string) *GitRef {
	q := r.q.Select("commit")
	q = q.Arg("id", id)

	return &GitRef{
		q: q,
		c: r.c,
	}
}

// Returns details on one tag.
func (r *GitRepository) Tag(name string) *GitRef {
	q := r.q.Select("tag")
	q = q.Arg("name", name)

	return &GitRef{
		q: q,
		c: r.c,
	}
}

// Information about the host execution environment.
type Host struct {
	q *querybuilder.Selection
	c graphql.Client
}

// HostDirectoryOpts contains options for Host.Directory
type HostDirectoryOpts struct {
	// Exclude artifacts that match the given pattern (e.g., ["node_modules/", ".git*"]).
	Exclude []string
	// Include only artifacts that match the given pattern (e.g., ["app/", "package.*"]).
	Include []string
}

// Accesses a directory on the host.
func (r *Host) Directory(path string, opts ...HostDirectoryOpts) *Directory {
	q := r.q.Select("directory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `exclude` optional argument
		if !querybuilder.IsZeroValue(opts[i].Exclude) {
			q = q.Arg("exclude", opts[i].Exclude)
		}
		// `include` optional argument
		if !querybuilder.IsZeroValue(opts[i].Include) {
			q = q.Arg("include", opts[i].Include)
		}
	}
	q = q.Arg("path", path)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Accesses a file on the host.
func (r *Host) File(path string) *File {
	q := r.q.Select("file")
	q = q.Arg("path", path)

	return &File{
		q: q,
		c: r.c,
	}
}

// HostServiceOpts contains options for Host.Service
type HostServiceOpts struct {
	// Upstream host to forward traffic to.
	Host string
}

// Creates a service that forwards traffic to a specified address via the host.
func (r *Host) Service(ports []PortForward, opts ...HostServiceOpts) *Service {
	q := r.q.Select("service")
	for i := len(opts) - 1; i >= 0; i-- {
		// `host` optional argument
		if !querybuilder.IsZeroValue(opts[i].Host) {
			q = q.Arg("host", opts[i].Host)
		}
	}
	q = q.Arg("ports", ports)

	return &Service{
		q: q,
		c: r.c,
	}
}

// Sets a secret given a user-defined name and the file path on the host, and returns the secret.
// The file is limited to a size of 512000 bytes.
func (r *Host) SetSecretFile(name string, path string) *Secret {
	q := r.q.Select("setSecretFile")
	q = q.Arg("name", name)
	q = q.Arg("path", path)

	return &Secret{
		q: q,
		c: r.c,
	}
}

// HostTunnelOpts contains options for Host.Tunnel
type HostTunnelOpts struct {
	// Map each service port to the same port on the host, as if the service were
	// running natively.
	//
	// Note: enabling may result in port conflicts.
	Native bool
	// Configure explicit port forwarding rules for the tunnel.
	//
	// If a port's frontend is unspecified or 0, a random port will be chosen by
	// the host.
	//
	// If no ports are given, all of the service's ports are forwarded. If native
	// is true, each port maps to the same port on the host. If native is false,
	// each port maps to a random port chosen by the host.
	//
	// If ports are given and native is true, the ports are additive.
	Ports []PortForward
}

// Creates a tunnel that forwards traffic from the host to a service.
func (r *Host) Tunnel(service *Service, opts ...HostTunnelOpts) *Service {
	assertNotNil("service", service)
	q := r.q.Select("tunnel")
	for i := len(opts) - 1; i >= 0; i-- {
		// `native` optional argument
		if !querybuilder.IsZeroValue(opts[i].Native) {
			q = q.Arg("native", opts[i].Native)
		}
		// `ports` optional argument
		if !querybuilder.IsZeroValue(opts[i].Ports) {
			q = q.Arg("ports", opts[i].Ports)
		}
	}
	q = q.Arg("service", service)

	return &Service{
		q: q,
		c: r.c,
	}
}

// Accesses a Unix socket on the host.
func (r *Host) UnixSocket(path string) *Socket {
	q := r.q.Select("unixSocket")
	q = q.Arg("path", path)

	return &Socket{
		q: q,
		c: r.c,
	}
}

// A simple key value object that represents a label.
type Label struct {
	q *querybuilder.Selection
	c graphql.Client

	name  *string
	value *string
}

// The label name.
func (r *Label) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The label value.
func (r *Label) Value(ctx context.Context) (string, error) {
	if r.value != nil {
		return *r.value, nil
	}
	q := r.q.Select("value")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A definition of a list type in a Module.
type ListTypeDef struct {
	q *querybuilder.Selection
	c graphql.Client
}

// The type of the elements in the list
func (r *ListTypeDef) ElementTypeDef() *TypeDef {
	q := r.q.Select("elementTypeDef")

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

type Module struct {
	q *querybuilder.Selection
	c graphql.Client

	description            *string
	id                     *ModuleID
	name                   *string
	sdk                    *string
	serve                  *Void
	sourceDirectorySubPath *string
}
type WithModuleFunc func(r *Module) *Module

// With calls the provided function with current Module.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Module) With(f WithModuleFunc) *Module {
	return f(r)
}

// Modules used by this module
func (r *Module) Dependencies(ctx context.Context) ([]Module, error) {
	q := r.q.Select("dependencies")

	q = q.Select("id")

	type dependencies struct {
		Id ModuleID
	}

	convert := func(fields []dependencies) []Module {
		out := []Module{}

		for i := range fields {
			val := Module{id: &fields[i].Id}
			val.q = querybuilder.Query().Select("loadModuleFromID").Arg("id", fields[i].Id)
			val.c = r.c
			out = append(out, val)
		}

		return out
	}
	var response []dependencies

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// The dependencies as configured by the module
func (r *Module) DependencyConfig(ctx context.Context) ([]string, error) {
	q := r.q.Select("dependencyConfig")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The doc string of the module, if any
func (r *Module) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The code generated by the SDK's runtime
func (r *Module) GeneratedCode() *GeneratedCode {
	q := r.q.Select("generatedCode")

	return &GeneratedCode{
		q: q,
		c: r.c,
	}
}

// The ID of the module
func (r *Module) ID(ctx context.Context) (ModuleID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response ModuleID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Module) XXX_GraphQLType() string {
	return "Module"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Module) XXX_GraphQLIDType() string {
	return "ModuleID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Module) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Module) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Module) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadModuleFromID(ModuleID(id))
	return nil
}

// The name of the module
func (r *Module) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Objects served by this module
func (r *Module) Objects(ctx context.Context) ([]TypeDef, error) {
	q := r.q.Select("objects")

	q = q.Select("id")

	type objects struct {
		Id TypeDefID
	}

	convert := func(fields []objects) []TypeDef {
		out := []TypeDef{}

		for i := range fields {
			val := TypeDef{id: &fields[i].Id}
			val.q = querybuilder.Query().Select("loadTypeDefFromID").Arg("id", fields[i].Id)
			val.c = r.c
			out = append(out, val)
		}

		return out
	}
	var response []objects

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// The SDK used by this module. Either a name of a builtin SDK or a module ref pointing to the SDK's implementation.
func (r *Module) SDK(ctx context.Context) (string, error) {
	if r.sdk != nil {
		return *r.sdk, nil
	}
	q := r.q.Select("sdk")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Serve a module's API in the current session.
//
//	Note: this can only be called once per session.
//	In the future, it could return a stream or service to remove the side effect.
func (r *Module) Serve(ctx context.Context) (Void, error) {
	if r.serve != nil {
		return *r.serve, nil
	}
	q := r.q.Select("serve")

	var response Void

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The directory containing the module's source code
func (r *Module) SourceDirectory() *Directory {
	q := r.q.Select("sourceDirectory")

	return &Directory{
		q: q,
		c: r.c,
	}
}

// The module's subpath within the source directory
func (r *Module) SourceDirectorySubPath(ctx context.Context) (string, error) {
	if r.sourceDirectorySubPath != nil {
		return *r.sourceDirectorySubPath, nil
	}
	q := r.q.Select("sourceDirectorySubPath")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// This module plus the given Object type and associated functions
func (r *Module) WithObject(object *TypeDef) *Module {
	assertNotNil("object", object)
	q := r.q.Select("withObject")
	q = q.Arg("object", object)

	return &Module{
		q: q,
		c: r.c,
	}
}

// Static configuration for a module (e.g. parsed contents of dagger.json)
type ModuleConfig struct {
	q *querybuilder.Selection
	c graphql.Client

	name *string
	root *string
	sdk  *string
}

// Modules that this module depends on.
func (r *ModuleConfig) Dependencies(ctx context.Context) ([]string, error) {
	q := r.q.Select("dependencies")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Exclude these file globs when loading the module root.
func (r *ModuleConfig) Exclude(ctx context.Context) ([]string, error) {
	q := r.q.Select("exclude")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Include only these file globs when loading the module root.
func (r *ModuleConfig) Include(ctx context.Context) ([]string, error) {
	q := r.q.Select("include")

	var response []string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The name of the module.
func (r *ModuleConfig) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The root directory of the module's project, which may be above the module source code.
func (r *ModuleConfig) Root(ctx context.Context) (string, error) {
	if r.root != nil {
		return *r.root, nil
	}
	q := r.q.Select("root")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Either the name of a built-in SDK ('go', 'python', etc.) OR a module reference pointing to the SDK's module implementation.
func (r *ModuleConfig) SDK(ctx context.Context) (string, error) {
	if r.sdk != nil {
		return *r.sdk, nil
	}
	q := r.q.Select("sdk")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

type Node struct {
	q *querybuilder.Selection
	c graphql.Client

	lint    *string
	publish *string
	start   *string
	test    *string
}
type WithNodeFunc func(r *Node) *Node

// With calls the provided function with current Node.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Node) With(f WithNodeFunc) *Node {
	return f(r)
}

// Build returns the Container with the source built.
func (r *Node) Build() *Node {
	q := r.q.Select("build")

	return &Node{
		q: q,
		c: r.c,
	}
}

// Container returns Node container.
func (r *Node) Container() *Container {
	q := r.q.Select("container")

	return &Container{
		q: q,
		c: r.c,
	}
}

func (r *Node) Ctr() *Container {
	q := r.q.Select("ctr")

	return &Container{
		q: q,
		c: r.c,
	}
}

// Install adds given package.
func (r *Node) Install(pkgs []string) *Node {
	q := r.q.Select("install")
	q = q.Arg("pkgs", pkgs)

	return &Node{
		q: q,
		c: r.c,
	}
}

// Lint returns the output of the lint command.
func (r *Node) Lint(ctx context.Context) (string, error) {
	if r.lint != nil {
		return *r.lint, nil
	}
	q := r.q.Select("lint")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// NodePublishOpts contains options for Node.Publish
type NodePublishOpts struct {
	// access permission of the package
	Access string
	// whether to do a dry run instead of an actual publish
	DryRun bool
}

// Publish publishes the source code to npm registry.
func (r *Node) Publish(ctx context.Context, tokenSecret *Secret, version string, opts ...NodePublishOpts) (string, error) {
	assertNotNil("tokenSecret", tokenSecret)
	if r.publish != nil {
		return *r.publish, nil
	}
	q := r.q.Select("publish")
	for i := len(opts) - 1; i >= 0; i-- {
		// `access` optional argument
		if !querybuilder.IsZeroValue(opts[i].Access) {
			q = q.Arg("access", opts[i].Access)
		}
		// `dryRun` optional argument
		if !querybuilder.IsZeroValue(opts[i].DryRun) {
			q = q.Arg("dryRun", opts[i].DryRun)
		}
	}
	q = q.Arg("tokenSecret", tokenSecret)
	q = q.Arg("version", version)

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Run returns the container with the command set.
func (r *Node) Run(args []string) *Container {
	q := r.q.Select("run")
	q = q.Arg("args", args)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Start returns the output of the code executed.
func (r *Node) Start(ctx context.Context) (string, error) {
	if r.start != nil {
		return *r.start, nil
	}
	q := r.q.Select("start")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Test returns the result of the test executed.
func (r *Node) Test(ctx context.Context) (string, error) {
	if r.test != nil {
		return *r.test, nil
	}
	q := r.q.Select("test")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// WithContainer returns Node container with the given container.
func (r *Node) WithContainer(ctr *Container) *Node {
	assertNotNil("ctr", ctr)
	q := r.q.Select("withContainer")
	q = q.Arg("ctr", ctr)

	return &Node{
		q: q,
		c: r.c,
	}
}

// WithNpm returns Node container with npm configured as package manager.
func (r *Node) WithNpm() *Node {
	q := r.q.Select("withNpm")

	return &Node{
		q: q,
		c: r.c,
	}
}

// WithSource returns the Node container with source and cache set in it.
func (r *Node) WithSource(source *Directory) *Node {
	assertNotNil("source", source)
	q := r.q.Select("withSource")
	q = q.Arg("source", source)

	return &Node{
		q: q,
		c: r.c,
	}
}

// WithVersion returns Node container with given image version.
func (r *Node) WithVersion(version string) *Node {
	q := r.q.Select("withVersion")
	q = q.Arg("version", version)

	return &Node{
		q: q,
		c: r.c,
	}
}

// WithYarn returns Node container with yarn configured as package manager.
func (r *Node) WithYarn() *Node {
	q := r.q.Select("withYarn")

	return &Node{
		q: q,
		c: r.c,
	}
}

// A definition of a custom object defined in a Module.
type ObjectTypeDef struct {
	q *querybuilder.Selection
	c graphql.Client

	description *string
	name        *string
}

// The doc string for the object, if any
func (r *ObjectTypeDef) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Static fields defined on this object, if any
func (r *ObjectTypeDef) Fields(ctx context.Context) ([]FieldTypeDef, error) {
	q := r.q.Select("fields")

	q = q.Select("description name")

	type fields struct {
		Description string
		Name        string
	}

	convert := func(fields []fields) []FieldTypeDef {
		out := []FieldTypeDef{}

		for i := range fields {
			val := FieldTypeDef{description: &fields[i].Description, name: &fields[i].Name}
			out = append(out, val)
		}

		return out
	}
	var response []fields

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// Functions defined on this object, if any
func (r *ObjectTypeDef) Functions(ctx context.Context) ([]Function, error) {
	q := r.q.Select("functions")

	q = q.Select("id")

	type functions struct {
		Id FunctionID
	}

	convert := func(fields []functions) []Function {
		out := []Function{}

		for i := range fields {
			val := Function{id: &fields[i].Id}
			val.q = querybuilder.Query().Select("loadFunctionFromID").Arg("id", fields[i].Id)
			val.c = r.c
			out = append(out, val)
		}

		return out
	}
	var response []functions

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// The name of the object
func (r *ObjectTypeDef) Name(ctx context.Context) (string, error) {
	if r.name != nil {
		return *r.name, nil
	}
	q := r.q.Select("name")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A port exposed by a container.
type Port struct {
	q *querybuilder.Selection
	c graphql.Client

	description *string
	port        *int
	protocol    *NetworkProtocol
}

// The port description.
func (r *Port) Description(ctx context.Context) (string, error) {
	if r.description != nil {
		return *r.description, nil
	}
	q := r.q.Select("description")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The port number.
func (r *Port) Port(ctx context.Context) (int, error) {
	if r.port != nil {
		return *r.port, nil
	}
	q := r.q.Select("port")

	var response int

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// The transport layer network protocol.
func (r *Port) Protocol(ctx context.Context) (NetworkProtocol, error) {
	if r.protocol != nil {
		return *r.protocol, nil
	}
	q := r.q.Select("protocol")

	var response NetworkProtocol

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

type WithClientFunc func(r *Client) *Client

// With calls the provided function with current Client.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *Client) With(f WithClientFunc) *Client {
	return f(r)
}

// Constructs a cache volume for a given cache key.
func (r *Client) CacheVolume(key string) *CacheVolume {
	q := r.q.Select("cacheVolume")
	q = q.Arg("key", key)

	return &CacheVolume{
		q: q,
		c: r.c,
	}
}

// Checks if the current Dagger Engine is compatible with an SDK's required version.
func (r *Client) CheckVersionCompatibility(ctx context.Context, version string) (bool, error) {
	q := r.q.Select("checkVersionCompatibility")
	q = q.Arg("version", version)

	var response bool

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// ContainerOpts contains options for Client.Container
type ContainerOpts struct {
	ID ContainerID

	Platform Platform
}

// Creates a scratch container or loads one by ID.
//
// Optional platform argument initializes new containers to execute and publish
// as that platform. Platform defaults to that of the builder's host.
func (r *Client) Container(opts ...ContainerOpts) *Container {
	q := r.q.Select("container")
	for i := len(opts) - 1; i >= 0; i-- {
		// `id` optional argument
		if !querybuilder.IsZeroValue(opts[i].ID) {
			q = q.Arg("id", opts[i].ID)
		}
		// `platform` optional argument
		if !querybuilder.IsZeroValue(opts[i].Platform) {
			q = q.Arg("platform", opts[i].Platform)
		}
	}

	return &Container{
		q: q,
		c: r.c,
	}
}

// The FunctionCall context that the SDK caller is currently executing in.
// If the caller is not currently executing in a function, this will return
// an error.
func (r *Client) CurrentFunctionCall() *FunctionCall {
	q := r.q.Select("currentFunctionCall")

	return &FunctionCall{
		q: q,
		c: r.c,
	}
}

// The module currently being served in the session, if any.
func (r *Client) CurrentModule() *Module {
	q := r.q.Select("currentModule")

	return &Module{
		q: q,
		c: r.c,
	}
}

// The default platform of the builder.
func (r *Client) DefaultPlatform(ctx context.Context) (Platform, error) {
	q := r.q.Select("defaultPlatform")

	var response Platform

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// DirectoryOpts contains options for Client.Directory
type DirectoryOpts struct {
	ID DirectoryID
}

// Creates an empty directory or loads one by ID.
func (r *Client) Directory(opts ...DirectoryOpts) *Directory {
	q := r.q.Select("directory")
	for i := len(opts) - 1; i >= 0; i-- {
		// `id` optional argument
		if !querybuilder.IsZeroValue(opts[i].ID) {
			q = q.Arg("id", opts[i].ID)
		}
	}

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Loads a file by ID.
//
// Deprecated: Use LoadFileFromID instead.
func (r *Client) File(id FileID) *File {
	q := r.q.Select("file")
	q = q.Arg("id", id)

	return &File{
		q: q,
		c: r.c,
	}
}

// Create a function.
func (r *Client) Function(name string, returnType *TypeDef) *Function {
	assertNotNil("returnType", returnType)
	q := r.q.Select("function")
	q = q.Arg("name", name)
	q = q.Arg("returnType", returnType)

	return &Function{
		q: q,
		c: r.c,
	}
}

// Create a code generation result, given a directory containing the generated
// code.
func (r *Client) GeneratedCode(code *Directory) *GeneratedCode {
	assertNotNil("code", code)
	q := r.q.Select("generatedCode")
	q = q.Arg("code", code)

	return &GeneratedCode{
		q: q,
		c: r.c,
	}
}

// GitOpts contains options for Client.Git
type GitOpts struct {
	// Set to true to keep .git directory.
	KeepGitDir bool
	// Set SSH known hosts
	SSHKnownHosts string
	// Set SSH auth socket
	SSHAuthSocket *Socket
	// A service which must be started before the repo is fetched.
	ExperimentalServiceHost *Service
}

// Queries a git repository.
func (r *Client) Git(url string, opts ...GitOpts) *GitRepository {
	q := r.q.Select("git")
	for i := len(opts) - 1; i >= 0; i-- {
		// `keepGitDir` optional argument
		if !querybuilder.IsZeroValue(opts[i].KeepGitDir) {
			q = q.Arg("keepGitDir", opts[i].KeepGitDir)
		}
		// `sshKnownHosts` optional argument
		if !querybuilder.IsZeroValue(opts[i].SSHKnownHosts) {
			q = q.Arg("sshKnownHosts", opts[i].SSHKnownHosts)
		}
		// `sshAuthSocket` optional argument
		if !querybuilder.IsZeroValue(opts[i].SSHAuthSocket) {
			q = q.Arg("sshAuthSocket", opts[i].SSHAuthSocket)
		}
		// `experimentalServiceHost` optional argument
		if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) {
			q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost)
		}
	}
	q = q.Arg("url", url)

	return &GitRepository{
		q: q,
		c: r.c,
	}
}

// Queries the host environment.
func (r *Client) Host() *Host {
	q := r.q.Select("host")

	return &Host{
		q: q,
		c: r.c,
	}
}

// HTTPOpts contains options for Client.HTTP
type HTTPOpts struct {
	// A service which must be started before the URL is fetched.
	ExperimentalServiceHost *Service
}

// Returns a file containing an http remote url content.
func (r *Client) HTTP(url string, opts ...HTTPOpts) *File {
	q := r.q.Select("http")
	for i := len(opts) - 1; i >= 0; i-- {
		// `experimentalServiceHost` optional argument
		if !querybuilder.IsZeroValue(opts[i].ExperimentalServiceHost) {
			q = q.Arg("experimentalServiceHost", opts[i].ExperimentalServiceHost)
		}
	}
	q = q.Arg("url", url)

	return &File{
		q: q,
		c: r.c,
	}
}

// Load a CacheVolume from its ID.
func (r *Client) LoadCacheVolumeFromID(id CacheVolumeID) *CacheVolume {
	q := r.q.Select("loadCacheVolumeFromID")
	q = q.Arg("id", id)

	return &CacheVolume{
		q: q,
		c: r.c,
	}
}

// Loads a container from an ID.
func (r *Client) LoadContainerFromID(id ContainerID) *Container {
	q := r.q.Select("loadContainerFromID")
	q = q.Arg("id", id)

	return &Container{
		q: q,
		c: r.c,
	}
}

// Load a Directory from its ID.
func (r *Client) LoadDirectoryFromID(id DirectoryID) *Directory {
	q := r.q.Select("loadDirectoryFromID")
	q = q.Arg("id", id)

	return &Directory{
		q: q,
		c: r.c,
	}
}

// Load a File from its ID.
func (r *Client) LoadFileFromID(id FileID) *File {
	q := r.q.Select("loadFileFromID")
	q = q.Arg("id", id)

	return &File{
		q: q,
		c: r.c,
	}
}

// Load a function argument by ID.
func (r *Client) LoadFunctionArgFromID(id FunctionArgID) *FunctionArg {
	q := r.q.Select("loadFunctionArgFromID")
	q = q.Arg("id", id)

	return &FunctionArg{
		q: q,
		c: r.c,
	}
}

// Load a function by ID.
func (r *Client) LoadFunctionFromID(id FunctionID) *Function {
	q := r.q.Select("loadFunctionFromID")
	q = q.Arg("id", id)

	return &Function{
		q: q,
		c: r.c,
	}
}

// Load a GeneratedCode by ID.
func (r *Client) LoadGeneratedCodeFromID(id GeneratedCodeID) *GeneratedCode {
	q := r.q.Select("loadGeneratedCodeFromID")
	q = q.Arg("id", id)

	return &GeneratedCode{
		q: q,
		c: r.c,
	}
}

// Load a module by ID.
func (r *Client) LoadModuleFromID(id ModuleID) *Module {
	q := r.q.Select("loadModuleFromID")
	q = q.Arg("id", id)

	return &Module{
		q: q,
		c: r.c,
	}
}

// Load a Secret from its ID.
func (r *Client) LoadSecretFromID(id SecretID) *Secret {
	q := r.q.Select("loadSecretFromID")
	q = q.Arg("id", id)

	return &Secret{
		q: q,
		c: r.c,
	}
}

// Loads a service from ID.
func (r *Client) LoadServiceFromID(id ServiceID) *Service {
	q := r.q.Select("loadServiceFromID")
	q = q.Arg("id", id)

	return &Service{
		q: q,
		c: r.c,
	}
}

// Load a Socket from its ID.
func (r *Client) LoadSocketFromID(id SocketID) *Socket {
	q := r.q.Select("loadSocketFromID")
	q = q.Arg("id", id)

	return &Socket{
		q: q,
		c: r.c,
	}
}

// Load a TypeDef by ID.
func (r *Client) LoadTypeDefFromID(id TypeDefID) *TypeDef {
	q := r.q.Select("loadTypeDefFromID")
	q = q.Arg("id", id)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// Create a new module.
func (r *Client) Module() *Module {
	q := r.q.Select("module")

	return &Module{
		q: q,
		c: r.c,
	}
}

// ModuleConfigOpts contains options for Client.ModuleConfig
type ModuleConfigOpts struct {
	Subpath string
}

// Load the static configuration for a module from the given source directory and optional subpath.
func (r *Client) ModuleConfig(sourceDirectory *Directory, opts ...ModuleConfigOpts) *ModuleConfig {
	assertNotNil("sourceDirectory", sourceDirectory)
	q := r.q.Select("moduleConfig")
	for i := len(opts) - 1; i >= 0; i-- {
		// `subpath` optional argument
		if !querybuilder.IsZeroValue(opts[i].Subpath) {
			q = q.Arg("subpath", opts[i].Subpath)
		}
	}
	q = q.Arg("sourceDirectory", sourceDirectory)

	return &ModuleConfig{
		q: q,
		c: r.c,
	}
}

func (r *Client) Node() *Node {
	q := r.q.Select("node")

	return &Node{
		q: q,
		c: r.c,
	}
}

// PipelineOpts contains options for Client.Pipeline
type PipelineOpts struct {
	// Pipeline description.
	Description string
	// Pipeline labels.
	Labels []PipelineLabel
}

// Creates a named sub-pipeline.
func (r *Client) Pipeline(name string, opts ...PipelineOpts) *Client {
	q := r.q.Select("pipeline")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
		// `labels` optional argument
		if !querybuilder.IsZeroValue(opts[i].Labels) {
			q = q.Arg("labels", opts[i].Labels)
		}
	}
	q = q.Arg("name", name)

	return &Client{
		q: q,
		c: r.c,
	}
}

// Loads a secret from its ID.
//
// Deprecated: Use LoadSecretFromID instead
func (r *Client) Secret(id SecretID) *Secret {
	q := r.q.Select("secret")
	q = q.Arg("id", id)

	return &Secret{
		q: q,
		c: r.c,
	}
}

// Sets a secret given a user defined name to its plaintext and returns the secret.
// The plaintext value is limited to a size of 128000 bytes.
func (r *Client) SetSecret(name string, plaintext string) *Secret {
	q := r.q.Select("setSecret")
	q = q.Arg("name", name)
	q = q.Arg("plaintext", plaintext)

	return &Secret{
		q: q,
		c: r.c,
	}
}

// SocketOpts contains options for Client.Socket
type SocketOpts struct {
	ID SocketID
}

// Loads a socket by its ID.
//
// Deprecated: Use LoadSocketFromID instead.
func (r *Client) Socket(opts ...SocketOpts) *Socket {
	q := r.q.Select("socket")
	for i := len(opts) - 1; i >= 0; i-- {
		// `id` optional argument
		if !querybuilder.IsZeroValue(opts[i].ID) {
			q = q.Arg("id", opts[i].ID)
		}
	}

	return &Socket{
		q: q,
		c: r.c,
	}
}

func (r *Client) Ttlsh() *Ttlsh {
	q := r.q.Select("ttlsh")

	return &Ttlsh{
		q: q,
		c: r.c,
	}
}

// Create a new TypeDef.
func (r *Client) TypeDef() *TypeDef {
	q := r.q.Select("typeDef")

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// A reference to a secret value, which can be handled more safely than the value itself.
type Secret struct {
	q *querybuilder.Selection
	c graphql.Client

	id        *SecretID
	plaintext *string
}

// The identifier for this secret.
func (r *Secret) ID(ctx context.Context) (SecretID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response SecretID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Secret) XXX_GraphQLType() string {
	return "Secret"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Secret) XXX_GraphQLIDType() string {
	return "SecretID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Secret) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Secret) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Secret) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadSecretFromID(SecretID(id))
	return nil
}

// The value of this secret.
func (r *Secret) Plaintext(ctx context.Context) (string, error) {
	if r.plaintext != nil {
		return *r.plaintext, nil
	}
	q := r.q.Select("plaintext")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

type Service struct {
	q *querybuilder.Selection
	c graphql.Client

	endpoint *string
	hostname *string
	id       *ServiceID
	start    *ServiceID
	stop     *ServiceID
}

// ServiceEndpointOpts contains options for Service.Endpoint
type ServiceEndpointOpts struct {
	// The exposed port number for the endpoint
	Port int
	// Return a URL with the given scheme, eg. http for http://
	Scheme string
}

// Retrieves an endpoint that clients can use to reach this container.
//
// If no port is specified, the first exposed port is used. If none exist an error is returned.
//
// If a scheme is specified, a URL is returned. Otherwise, a host:port pair is returned.
func (r *Service) Endpoint(ctx context.Context, opts ...ServiceEndpointOpts) (string, error) {
	if r.endpoint != nil {
		return *r.endpoint, nil
	}
	q := r.q.Select("endpoint")
	for i := len(opts) - 1; i >= 0; i-- {
		// `port` optional argument
		if !querybuilder.IsZeroValue(opts[i].Port) {
			q = q.Arg("port", opts[i].Port)
		}
		// `scheme` optional argument
		if !querybuilder.IsZeroValue(opts[i].Scheme) {
			q = q.Arg("scheme", opts[i].Scheme)
		}
	}

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Retrieves a hostname which can be used by clients to reach this container.
func (r *Service) Hostname(ctx context.Context) (string, error) {
	if r.hostname != nil {
		return *r.hostname, nil
	}
	q := r.q.Select("hostname")

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A unique identifier for this service.
func (r *Service) ID(ctx context.Context) (ServiceID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response ServiceID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Service) XXX_GraphQLType() string {
	return "Service"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Service) XXX_GraphQLIDType() string {
	return "ServiceID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Service) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Service) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Service) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadServiceFromID(ServiceID(id))
	return nil
}

// Retrieves the list of ports provided by the service.
func (r *Service) Ports(ctx context.Context) ([]Port, error) {
	q := r.q.Select("ports")

	q = q.Select("description port protocol")

	type ports struct {
		Description string
		Port        int
		Protocol    NetworkProtocol
	}

	convert := func(fields []ports) []Port {
		out := []Port{}

		for i := range fields {
			val := Port{description: &fields[i].Description, port: &fields[i].Port, protocol: &fields[i].Protocol}
			out = append(out, val)
		}

		return out
	}
	var response []ports

	q = q.Bind(&response)

	err := q.Execute(ctx, r.c)
	if err != nil {
		return nil, err
	}

	return convert(response), nil
}

// Start the service and wait for its health checks to succeed.
//
// Services bound to a Container do not need to be manually started.
func (r *Service) Start(ctx context.Context) (*Service, error) {
	q := r.q.Select("start")

	return r, q.Execute(ctx, r.c)
}

// Stop the service.
func (r *Service) Stop(ctx context.Context) (*Service, error) {
	q := r.q.Select("stop")

	return r, q.Execute(ctx, r.c)
}

type Socket struct {
	q *querybuilder.Selection
	c graphql.Client

	id *SocketID
}

// The content-addressed identifier of the socket.
func (r *Socket) ID(ctx context.Context) (SocketID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response SocketID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *Socket) XXX_GraphQLType() string {
	return "Socket"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *Socket) XXX_GraphQLIDType() string {
	return "SocketID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *Socket) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *Socket) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *Socket) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadSocketFromID(SocketID(id))
	return nil
}

type Ttlsh struct {
	q *querybuilder.Selection
	c graphql.Client

	publish *string
}

// TtlshPublishOpts contains options for Ttlsh.Publish
type TtlshPublishOpts struct {
	// the repo to publish to, defaults to a random name
	Repo string
	// the tag to publish to, defaults to 10m
	Tag string
}

// Publish a container to ttl.sh
func (r *Ttlsh) Publish(ctx context.Context, ctr *Container, opts ...TtlshPublishOpts) (string, error) {
	assertNotNil("ctr", ctr)
	if r.publish != nil {
		return *r.publish, nil
	}
	q := r.q.Select("publish")
	for i := len(opts) - 1; i >= 0; i-- {
		// `repo` optional argument
		if !querybuilder.IsZeroValue(opts[i].Repo) {
			q = q.Arg("repo", opts[i].Repo)
		}
		// `tag` optional argument
		if !querybuilder.IsZeroValue(opts[i].Tag) {
			q = q.Arg("tag", opts[i].Tag)
		}
	}
	q = q.Arg("ctr", ctr)

	var response string

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// A definition of a parameter or return type in a Module.
type TypeDef struct {
	q *querybuilder.Selection
	c graphql.Client

	id       *TypeDefID
	kind     *TypeDefKind
	optional *bool
}
type WithTypeDefFunc func(r *TypeDef) *TypeDef

// With calls the provided function with current TypeDef.
//
// This is useful for reusability and readability by not breaking the calling chain.
func (r *TypeDef) With(f WithTypeDefFunc) *TypeDef {
	return f(r)
}

// If kind is LIST, the list-specific type definition.
// If kind is not LIST, this will be null.
func (r *TypeDef) AsList() *ListTypeDef {
	q := r.q.Select("asList")

	return &ListTypeDef{
		q: q,
		c: r.c,
	}
}

// If kind is OBJECT, the object-specific type definition.
// If kind is not OBJECT, this will be null.
func (r *TypeDef) AsObject() *ObjectTypeDef {
	q := r.q.Select("asObject")

	return &ObjectTypeDef{
		q: q,
		c: r.c,
	}
}

func (r *TypeDef) ID(ctx context.Context) (TypeDefID, error) {
	if r.id != nil {
		return *r.id, nil
	}
	q := r.q.Select("id")

	var response TypeDefID

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// XXX_GraphQLType is an internal function. It returns the native GraphQL type name
func (r *TypeDef) XXX_GraphQLType() string {
	return "TypeDef"
}

// XXX_GraphQLIDType is an internal function. It returns the native GraphQL type name for the ID of this object
func (r *TypeDef) XXX_GraphQLIDType() string {
	return "TypeDefID"
}

// XXX_GraphQLID is an internal function. It returns the underlying type ID
func (r *TypeDef) XXX_GraphQLID(ctx context.Context) (string, error) {
	id, err := r.ID(ctx)
	if err != nil {
		return "", err
	}
	return string(id), nil
}

func (r *TypeDef) MarshalJSON() ([]byte, error) {
	id, err := r.ID(context.Background())
	if err != nil {
		return nil, err
	}
	return json.Marshal(id)
}
func (r *TypeDef) UnmarshalJSON(bs []byte) error {
	var id string
	err := json.Unmarshal(bs, &id)
	if err != nil {
		return err
	}
	*r = *dag.LoadTypeDefFromID(TypeDefID(id))
	return nil
}

// The kind of type this is (e.g. primitive, list, object)
func (r *TypeDef) Kind(ctx context.Context) (TypeDefKind, error) {
	if r.kind != nil {
		return *r.kind, nil
	}
	q := r.q.Select("kind")

	var response TypeDefKind

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// Whether this type can be set to null. Defaults to false.
func (r *TypeDef) Optional(ctx context.Context) (bool, error) {
	if r.optional != nil {
		return *r.optional, nil
	}
	q := r.q.Select("optional")

	var response bool

	q = q.Bind(&response)
	return response, q.Execute(ctx, r.c)
}

// TypeDefWithFieldOpts contains options for TypeDef.WithField
type TypeDefWithFieldOpts struct {
	// A doc string for the field, if any
	Description string
}

// Adds a static field for an Object TypeDef, failing if the type is not an object.
func (r *TypeDef) WithField(name string, typeDef *TypeDef, opts ...TypeDefWithFieldOpts) *TypeDef {
	assertNotNil("typeDef", typeDef)
	q := r.q.Select("withField")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
	}
	q = q.Arg("name", name)
	q = q.Arg("typeDef", typeDef)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// Adds a function for an Object TypeDef, failing if the type is not an object.
func (r *TypeDef) WithFunction(function *Function) *TypeDef {
	assertNotNil("function", function)
	q := r.q.Select("withFunction")
	q = q.Arg("function", function)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// Sets the kind of the type.
func (r *TypeDef) WithKind(kind TypeDefKind) *TypeDef {
	q := r.q.Select("withKind")
	q = q.Arg("kind", kind)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// Returns a TypeDef of kind List with the provided type for its elements.
func (r *TypeDef) WithListOf(elementType *TypeDef) *TypeDef {
	assertNotNil("elementType", elementType)
	q := r.q.Select("withListOf")
	q = q.Arg("elementType", elementType)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// TypeDefWithObjectOpts contains options for TypeDef.WithObject
type TypeDefWithObjectOpts struct {
	Description string
}

// Returns a TypeDef of kind Object with the provided name.
//
// Note that an object's fields and functions may be omitted if the intent is
// only to refer to an object. This is how functions are able to return their
// own object, or any other circular reference.
func (r *TypeDef) WithObject(name string, opts ...TypeDefWithObjectOpts) *TypeDef {
	q := r.q.Select("withObject")
	for i := len(opts) - 1; i >= 0; i-- {
		// `description` optional argument
		if !querybuilder.IsZeroValue(opts[i].Description) {
			q = q.Arg("description", opts[i].Description)
		}
	}
	q = q.Arg("name", name)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

// Sets whether this type can be set to null.
func (r *TypeDef) WithOptional(optional bool) *TypeDef {
	q := r.q.Select("withOptional")
	q = q.Arg("optional", optional)

	return &TypeDef{
		q: q,
		c: r.c,
	}
}

type CacheSharingMode string

func (CacheSharingMode) IsEnum() {}

const (
	Locked  CacheSharingMode = "LOCKED"
	Private CacheSharingMode = "PRIVATE"
	Shared  CacheSharingMode = "SHARED"
)

type ImageLayerCompression string

func (ImageLayerCompression) IsEnum() {}

const (
	Estargz      ImageLayerCompression = "EStarGZ"
	Gzip         ImageLayerCompression = "Gzip"
	Uncompressed ImageLayerCompression = "Uncompressed"
	Zstd         ImageLayerCompression = "Zstd"
)

type ImageMediaTypes string

func (ImageMediaTypes) IsEnum() {}

const (
	Dockermediatypes ImageMediaTypes = "DockerMediaTypes"
	Ocimediatypes    ImageMediaTypes = "OCIMediaTypes"
)

type NetworkProtocol string

func (NetworkProtocol) IsEnum() {}

const (
	Tcp NetworkProtocol = "TCP"
	Udp NetworkProtocol = "UDP"
)

type TypeDefKind string

func (TypeDefKind) IsEnum() {}

const (
	BooleanKind TypeDefKind = "BooleanKind"
	IntegerKind TypeDefKind = "IntegerKind"
	ListKind    TypeDefKind = "ListKind"
	ObjectKind  TypeDefKind = "ObjectKind"
	StringKind  TypeDefKind = "StringKind"
	VoidKind    TypeDefKind = "VoidKind"
)

type Client struct {
	c graphql.Client
	q *querybuilder.Selection
}

var dag *Client

func init() {
	gqlClient, q := getClientParams()
	dag = &Client{
		c: gqlClient,
		q: q,
	}
}

func getClientParams() (graphql.Client, *querybuilder.Selection) {
	portStr, ok := os.LookupEnv("DAGGER_SESSION_PORT")
	if !ok {
		panic("DAGGER_SESSION_PORT is not set")
	}
	port, err := strconv.Atoi(portStr)
	if err != nil {
		panic(fmt.Errorf("DAGGER_SESSION_PORT %q is invalid: %w", portStr, err))
	}

	sessionToken := os.Getenv("DAGGER_SESSION_TOKEN")
	if sessionToken == "" {
		panic("DAGGER_SESSION_TOKEN is not set")
	}

	host := fmt.Sprintf("127.0.0.1:%d", port)

	dialTransport := &http.Transport{
		DialContext: func(_ context.Context, _, _ string) (net.Conn, error) {
			return net.Dial("tcp", host)
		},
	}
	httpClient := &http.Client{
		Transport: roundTripperFunc(func(r *http.Request) (*http.Response, error) {
			r.SetBasicAuth(sessionToken, "")
			return dialTransport.RoundTrip(r)
		}),
	}
	gqlClient := graphql.NewClient(fmt.Sprintf("http://%s/query", host), httpClient)

	return gqlClient, querybuilder.Query()
}

// TODO: pollutes namespace, move to non internal package in dagger.io/dagger
type roundTripperFunc func(*http.Request) (*http.Response, error)

func (fn roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
	return fn(req)
}

func main() {
	ctx := context.Background()

	fnCall := dag.CurrentFunctionCall()
	parentName, err := fnCall.ParentName(ctx)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
	fnName, err := fnCall.Name(ctx)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
	parentJson, err := fnCall.Parent(ctx)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
	fnArgs, err := fnCall.InputArgs(ctx)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}

	inputArgs := map[string][]byte{}
	for _, fnArg := range fnArgs {
		argName, err := fnArg.Name(ctx)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(2)
		}
		argValue, err := fnArg.Value(ctx)
		if err != nil {
			fmt.Println(err.Error())
			os.Exit(2)
		}
		inputArgs[argName] = []byte(argValue)
	}

	result, err := invoke(ctx, []byte(parentJson), parentName, fnName, inputArgs)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
	resultBytes, err := json.Marshal(result)
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
	_, err = fnCall.ReturnValue(ctx, JSON(resultBytes))
	if err != nil {
		fmt.Println(err.Error())
		os.Exit(2)
	}
}

func invoke(ctx context.Context, parentJSON []byte, parentName string, fnName string, inputArgs map[string][]byte) (any, error) {
	switch parentName {
	case "Mymod":
		switch fnName {
		case "Test":
			var err error
			var parent Mymod
			err = json.Unmarshal(parentJSON, &parent)
			if err != nil {
				fmt.Println(err.Error())
				os.Exit(2)
			}
			var nodeVersion Optional[string]
			if inputArgs["nodeVersion"] != nil {
				err = json.Unmarshal([]byte(inputArgs["nodeVersion"]), &nodeVersion)
				if err != nil {
					fmt.Println(err.Error())
					os.Exit(2)
				}
			}
			return (*Mymod).Test(&parent, ctx, nodeVersion)
		case "Build":
			var err error
			var parent Mymod
			err = json.Unmarshal(parentJSON, &parent)
			if err != nil {
				fmt.Println(err.Error())
				os.Exit(2)
			}
			var nodeVersion Optional[string]
			if inputArgs["nodeVersion"] != nil {
				err = json.Unmarshal([]byte(inputArgs["nodeVersion"]), &nodeVersion)
				if err != nil {
					fmt.Println(err.Error())
					os.Exit(2)
				}
			}
			return (*Mymod).Build(&parent, nodeVersion), nil
		case "Publish":
			var err error
			var parent Mymod
			err = json.Unmarshal(parentJSON, &parent)
			if err != nil {
				fmt.Println(err.Error())
				os.Exit(2)
			}
			var nodeVersion Optional[string]
			if inputArgs["nodeVersion"] != nil {
				err = json.Unmarshal([]byte(inputArgs["nodeVersion"]), &nodeVersion)
				if err != nil {
					fmt.Println(err.Error())
					os.Exit(2)
				}
			}
			return (*Mymod).Publish(&parent, ctx, nodeVersion)
		default:
			return nil, fmt.Errorf("unknown function %s", fnName)
		}
	case "":
		return dag.CurrentModule().
			WithObject(
				dag.TypeDef().WithObject("Mymod").
					WithFunction(
						dag.Function("Test",
							dag.TypeDef().WithKind(StringKind)).
							WithArg("nodeVersion", dag.TypeDef().WithKind(StringKind).WithOptional(true))).
					WithFunction(
						dag.Function("Build",
							dag.TypeDef().WithObject("Directory")).
							WithArg("nodeVersion", dag.TypeDef().WithKind(StringKind).WithOptional(true))).
					WithFunction(
						dag.Function("Publish",
							dag.TypeDef().WithKind(StringKind)).
							WithArg("nodeVersion", dag.TypeDef().WithKind(StringKind).WithOptional(true)))), nil
	default:
		return nil, fmt.Errorf("unknown object %s", parentName)
	}
}
