# `AtpClient.Config`
[🔗](https://github.com/jcschuster/AtpClient/blob/v0.6.0/lib/atp_client/config.ex#L1)

Resolves configuration for each backend by merging (in increasing precedence):

  1. Library defaults declared in this module under `@defaults`.
  2. Application configuration under the `:atp_client` OTP app.
  3. Per-call options passed as a `Keyword.t()`.

Defaults are merged *per key*, so a partial `config :atp_client, :sotptp, …`
in `config.exs` only overrides the keys it names; it cannot accidentally
clobber `:url` and leave the library with no endpoint.

## Example

In `config/config.exs`:

    config :atp_client, :starexec,
      base_url: "https://starexec.example.org/starexec",
      username: System.get_env("STAREXEC_USER"),
      password: System.get_env("STAREXEC_PASS")

    config :atp_client, :isabelle,
      host: "isabelle.example.org",
      port: 9999,
      password: System.get_env("ISABELLE_PASSWORD"),
      # `:local_dir` defaults to a subdirectory of `System.tmp_dir!/0`.
      # Only set it (and `:isabelle_dir`) when the BEAM and the Isabelle
      # server see the shared directory under different paths.
      session: "HOL"

Any setting may be overridden per call. For instance,

    AtpClient.Isabelle.query(theory, "Example", session: "Main")

forces the `Main` session for that single query regardless of what is set
in `config.exs`.

# `backend`

```elixir
@type backend() :: :sotptp | :starexec | :isabelle | :local_exec
```

# `defaults`

```elixir
@spec defaults() :: keyword()
```

Returns the library defaults that `get/2` layers underneath the
Application env. Exposed mainly so tests and tooling can inspect what
ships out of the box without parsing `mix.exs`.

# `fetch`

```elixir
@spec fetch(backend(), atom(), any(), keyword()) :: any()
```

Returns the value of `key` from the resolved settings for `backend`, falling
back to the given `default` if unset or set to `nil`.

Per-call `opts` win over Application env, which wins over library defaults.

## Examples

    # Library default from `AtpClient.Config.defaults/0`.
    AtpClient.Config.fetch(:sotptp, :default_time_limit_sec, 5)
    # => 5

    # Per-call override wins over defaults and Application env.
    AtpClient.Config.fetch(:sotptp, :default_time_limit_sec, 5,
      default_time_limit_sec: 30)
    # => 30

# `fetch!`

```elixir
@spec fetch!(backend(), atom(), keyword()) :: any()
```

Returns the value of `key` from the resolved settings for `backend`, raising
a descriptive `ArgumentError` if unset or `nil`.

Use this for settings that have no sensible default (for example
`:base_url`, `:password`).

## Examples

    AtpClient.Config.fetch!(:sotptp, :url)
    # => "https://tptp.org/cgi-bin/SystemOnTPTPFormReply"

    AtpClient.Config.fetch!(:starexec, :base_url)
    # ** (ArgumentError) AtpClient: missing required setting `:base_url`
    #                    for backend `:starexec`. ...

# `get`

```elixir
@spec get(
  backend(),
  keyword()
) :: keyword()
```

Returns the fully resolved settings for the given backend as a keyword list.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
