# This file generated by `mix dagger.gen`. Please DO NOT EDIT.
defmodule Dagger.Function do
  @moduledoc "Function represents a resolver provided by a Module.\n\nA function always evaluates against a parent object and is given a set of named arguments."
  use Dagger.QueryBuilder
  @type t() :: %__MODULE__{}
  defstruct [:selection, :client]

  (
    @doc ""
    @spec args(t()) :: {:ok, [Dagger.FunctionArg.t()]} | {:error, term()}
    def args(%__MODULE__{} = function) do
      selection = select(function.selection, "args")
      selection = select(selection, "defaultValue description id name typeDef")

      with {:ok, data} <- execute(selection, function.client) do
        {:ok,
         data
         |> Enum.map(fn value ->
           elem_selection = Dagger.QueryBuilder.Selection.query()
           elem_selection = select(elem_selection, "loadFunctionArgFromID")
           elem_selection = arg(elem_selection, "id", value["id"])
           %Dagger.FunctionArg{selection: elem_selection, client: function.client}
         end)}
      end
    end
  )

  (
    @doc ""
    @spec description(t()) :: {:ok, Dagger.String.t()} | {:error, term()}
    def description(%__MODULE__{} = function) do
      selection = select(function.selection, "description")
      execute(selection, function.client)
    end
  )

  (
    @doc "A unique identifier for this Function."
    @spec id(t()) :: {:ok, Dagger.FunctionID.t()} | {:error, term()}
    def id(%__MODULE__{} = function) do
      selection = select(function.selection, "id")
      execute(selection, function.client)
    end
  )

  (
    @doc ""
    @spec name(t()) :: {:ok, Dagger.String.t()} | {:error, term()}
    def name(%__MODULE__{} = function) do
      selection = select(function.selection, "name")
      execute(selection, function.client)
    end
  )

  (
    @doc ""
    @spec return_type(t()) :: Dagger.TypeDef.t()
    def return_type(%__MODULE__{} = function) do
      selection = select(function.selection, "returnType")
      %Dagger.TypeDef{selection: selection, client: function.client}
    end
  )

  (
    @doc "Returns the function with the provided argument\n\n## Required Arguments\n\n* `name` - The name of the argument\n* `type_def` - The type of the argument\n\n## Optional Arguments\n\n* `description` - A doc string for the argument, if any\n* `default_value` - A default value to use for this argument if not explicitly set by the caller, if any"
    @spec with_arg(t(), Dagger.String.t(), Dagger.TypeDef.t(), keyword()) :: Dagger.Function.t()
    def with_arg(%__MODULE__{} = function, name, type_def, optional_args \\ []) do
      selection = select(function.selection, "withArg")
      selection = arg(selection, "name", name)

      (
        {:ok, id} = Dagger.TypeDef.id(type_def)
        selection = arg(selection, "typeDef", id)
      )

      selection =
        if is_nil(optional_args[:description]) do
          selection
        else
          arg(selection, "description", optional_args[:description])
        end

      selection =
        if is_nil(optional_args[:default_value]) do
          selection
        else
          arg(selection, "defaultValue", optional_args[:default_value])
        end

      %Dagger.Function{selection: selection, client: function.client}
    end
  )

  (
    @doc "Returns the function with the given doc string.\n\n## Required Arguments\n\n* `description` - The doc string to set."
    @spec with_description(t(), Dagger.String.t()) :: Dagger.Function.t()
    def with_description(%__MODULE__{} = function, description) do
      selection = select(function.selection, "withDescription")
      selection = arg(selection, "description", description)
      %Dagger.Function{selection: selection, client: function.client}
    end
  )
end
