# This file generated by `dagger_codegen`. Please DO NOT EDIT.
defmodule Dagger.JSONValue do
  @moduledoc """
  Dagger.JSONValue
  """

  use Dagger.Core.Base, kind: :object, name: "JSONValue"

  alias Dagger.Core.Client
  alias Dagger.Core.QueryBuilder, as: QB

  @derive Dagger.ID

  defstruct [:query_builder, :client]

  @type t() :: %__MODULE__{}

  @doc """
  Decode an array from json
  """
  @spec as_array(t()) :: {:ok, [Dagger.JSONValue.t()]} | {:error, term()}
  def as_array(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("asArray") |> QB.select("id")

    with {:ok, items} <- Client.execute(json_value.client, query_builder) do
      {:ok,
       for %{"id" => id} <- items do
         %Dagger.JSONValue{
           query_builder:
             QB.query()
             |> QB.select("loadJSONValueFromID")
             |> QB.put_arg("id", id),
           client: json_value.client
         }
       end}
    end
  end

  @doc """
  Decode a boolean from json
  """
  @spec as_boolean(t()) :: {:ok, boolean()} | {:error, term()}
  def as_boolean(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("asBoolean")

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  Decode an integer from json
  """
  @spec as_integer(t()) :: {:ok, integer()} | {:error, term()}
  def as_integer(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("asInteger")

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  Decode a string from json
  """
  @spec as_string(t()) :: {:ok, String.t()} | {:error, term()}
  def as_string(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("asString")

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  Return the value encoded as json
  """
  @spec contents(t(), [{:pretty, boolean() | nil}, {:indent, String.t() | nil}]) ::
          {:ok, Dagger.JSON.t()} | {:error, term()}
  def contents(%__MODULE__{} = json_value, optional_args \\ []) do
    query_builder =
      json_value.query_builder
      |> QB.select("contents")
      |> QB.maybe_put_arg("pretty", optional_args[:pretty])
      |> QB.maybe_put_arg("indent", optional_args[:indent])

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  Lookup the field at the given path, and return its value.
  """
  @spec field(t(), [String.t()]) :: Dagger.JSONValue.t()
  def field(%__MODULE__{} = json_value, path) do
    query_builder =
      json_value.query_builder |> QB.select("field") |> QB.put_arg("path", path)

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end

  @doc """
  List fields of the encoded object
  """
  @spec fields(t()) :: {:ok, [String.t()]} | {:error, term()}
  def fields(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("fields")

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  A unique identifier for this JSONValue.
  """
  @spec id(t()) :: {:ok, Dagger.JSONValueID.t()} | {:error, term()}
  def id(%__MODULE__{} = json_value) do
    query_builder =
      json_value.query_builder |> QB.select("id")

    Client.execute(json_value.client, query_builder)
  end

  @doc """
  Encode a boolean to json
  """
  @spec new_boolean(t(), boolean()) :: Dagger.JSONValue.t()
  def new_boolean(%__MODULE__{} = json_value, value) do
    query_builder =
      json_value.query_builder |> QB.select("newBoolean") |> QB.put_arg("value", value)

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end

  @doc """
  Encode an integer to json
  """
  @spec new_integer(t(), integer()) :: Dagger.JSONValue.t()
  def new_integer(%__MODULE__{} = json_value, value) do
    query_builder =
      json_value.query_builder |> QB.select("newInteger") |> QB.put_arg("value", value)

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end

  @doc """
  Encode a string to json
  """
  @spec new_string(t(), String.t()) :: Dagger.JSONValue.t()
  def new_string(%__MODULE__{} = json_value, value) do
    query_builder =
      json_value.query_builder |> QB.select("newString") |> QB.put_arg("value", value)

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end

  @doc """
  Return a new json value, decoded from the given content
  """
  @spec with_contents(t(), Dagger.JSON.t()) :: Dagger.JSONValue.t()
  def with_contents(%__MODULE__{} = json_value, contents) do
    query_builder =
      json_value.query_builder |> QB.select("withContents") |> QB.put_arg("contents", contents)

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end

  @doc """
  Set a new field at the given path
  """
  @spec with_field(t(), [String.t()], Dagger.JSONValue.t()) :: Dagger.JSONValue.t()
  def with_field(%__MODULE__{} = json_value, path, value) do
    query_builder =
      json_value.query_builder
      |> QB.select("withField")
      |> QB.put_arg("path", path)
      |> QB.put_arg("value", Dagger.ID.id!(value))

    %Dagger.JSONValue{
      query_builder: query_builder,
      client: json_value.client
    }
  end
end

defimpl Jason.Encoder, for: Dagger.JSONValue do
  def encode(json_value, opts) do
    {:ok, id} = Dagger.JSONValue.id(json_value)
    Jason.Encode.string(id, opts)
  end
end

defimpl Nestru.Decoder, for: Dagger.JSONValue do
  def decode_fields_hint(_struct, _context, id) do
    {:ok, Dagger.Client.load_json_value_from_id(Dagger.Global.dag(), id)}
  end
end
