// Code generated by dagger. DO NOT EDIT.

package {{.PackageName}}

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

	"github.com/Khan/genqlient/graphql"
	"github.com/vektah/gqlparser/v2/gqlerror"

	"{{.PackageImport}}/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 any] struct {
	value T
	isSet bool
}

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

// OptEmpty is a helper function to construct an empty Optional.
func OptEmpty[T any]() Optional[T] {
	return Optional[T]{}
}

// 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) {
	if o == nil {
		var empty T
		return empty, false
	}
	return o.value, o.isSet
}

// 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 {
	if o == nil {
		return defaultValue
	}
	if o.isSet {
		return o.value
	}
	return defaultValue
}

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)
}

type DaggerObject querybuilder.GraphQLMarshaller

func convertSlice[I any, O any](in []I, f func(I) O) []O {
  out := make([]O, len(in))
  for i, v := range in {
    out[i] = f(v)
  }
  return out
}

func convertOptionalVal[I any, O any](opt Optional[I], f func(I) O) Optional[O] {
	if !opt.isSet {
		return Optional[O]{}
	}
	return Optional[O]{value: f(opt.value), isSet: true}
}

// getCustomError parses a GraphQL error into a more specific error type.
func getCustomError(err error) error {
	var gqlErr *gqlerror.Error

	if !errors.As(err, &gqlErr) {
		return nil
	}

	ext := gqlErr.Extensions

	typ, ok := ext["_type"].(string)
	if !ok {
		return nil
	}

	if typ == "EXEC_ERROR" {
		e := &ExecError{
			original: err,
		}
		if code, ok := ext["exitCode"].(float64); ok {
			e.ExitCode = int(code)
		}
		if args, ok := ext["cmd"].([]interface{}); ok {
			cmd := make([]string, len(args))
			for i, v := range args {
				cmd[i] = v.(string)
			}
			e.Cmd = cmd
		}
		if stdout, ok := ext["stdout"].(string); ok {
			e.Stdout = stdout
		}
		if stderr, ok := ext["stderr"].(string); ok {
			e.Stderr = stderr
		}
		return e
	}

	return nil
}

// ExecError is an API error from an exec operation.
type ExecError struct {
	original error
	Cmd      []string
	ExitCode int
	Stdout   string
	Stderr   string
}

func (e *ExecError) Error() string {
	// As a default when just printing the error, include the stdout
	// and stderr for visibility
	return fmt.Sprintf(
		"%s\nStdout:\n%s\nStderr:\n%s",
		e.Message(),
		e.Stdout,
		e.Stderr,
	)
}

func (e *ExecError) Message() string {
	return e.original.Error()
}

func (e *ExecError) Unwrap() error {
	return e.original
}

{{ range .Types }}
{{ if eq .Kind "SCALAR" }}{{ template "_dagger.gen.go/scalar.go.tmpl" . }}{{ end }}
{{ if eq .Kind "OBJECT" }}{{ template "_dagger.gen.go/object.go.tmpl" . }}{{ end }}
{{ if eq .Kind "INPUT_OBJECT" }}{{ template "_dagger.gen.go/input.go.tmpl" . }}{{ end }}
{{ if eq .Kind "ENUM" }}{{ template "_dagger.gen.go/enum.go.tmpl" . }}{{ end }}
{{ end }}

{{ if IsModuleCode }}
{{ template "_dagger.gen.go/module.go.tmpl" $.Schema }}
{{ end }}