# `Angelus.Spice`
[🔗](https://github.com/MonsignorEduardo/angelus/blob/v0.0.2/lib/angelus/spice.ex#L1)

Public SPICE facade with v0.1 kernel policy validation.

# `default_kernel_files`

```elixir
@spec default_kernel_files() :: [String.t()]
```

Returns the list of kernel filenames required by the default v0.1 kernel set.

# `load_kernels`

```elixir
@spec load_kernels() :: {:ok, map()} | {:error, term()}
```

Loads the default v0.1 SPICE kernel set from `priv/kernels/`.

Equivalent to `load_kernels([])`.

## Returns

  * `{:ok, metadata}` on success, where `metadata` is a map describing the
    loaded kernel set.
  * `{:error, :worker_not_available}` if the native binary has not been compiled.
  * `{:error, :kernels_already_loaded}` if kernels are already loaded and
    `:replace` was not set.

# `load_kernels`

```elixir
@spec load_kernels(keyword() | [String.t()]) :: {:ok, map()} | {:error, term()}
```

Loads SPICE kernels from explicit paths or using options.

## Variants

### `load_kernels(opts)` — load default kernel set with options

`opts` is a keyword list. Supported keys:

  * `:base_path` — directory containing the kernel files (default:
    `"#{File.cwd!()}/priv/kernels"`).
  * `:replace` — when `true`, clears any previously loaded kernels before
    loading (default: `false`).

### `load_kernels(paths)` — load explicit kernel file paths

`paths` is a list of absolute file path strings. Use `load_kernels/2` to
pass options alongside explicit paths.

## Returns

  * `{:ok, metadata}` on success.
  * `{:error, {:invalid_kernel_set, reason}}` for invalid paths or missing files.
  * `{:error, :worker_not_available}` if the native binary has not been compiled.
  * `{:error, :kernels_already_loaded}` if kernels are already loaded and
    `:replace` was not set.
  * `{:error, {:unsupported_option, option}}` for unknown options.

# `load_kernels`

```elixir
@spec load_kernels(
  [String.t()],
  keyword()
) :: {:ok, map()} | {:error, term()}
```

Loads SPICE kernels from explicit paths with options.

`paths` must be a list of absolute file path strings that form a valid v0.1
kernel set. `opts` supports `:replace` (boolean, default `false`).

## Returns

  * `{:ok, metadata}` on success.
  * `{:error, {:invalid_kernel_set, reason}}` for invalid paths or missing files.
  * `{:error, :kernels_already_loaded}` if kernels are loaded and `:replace` is false.
  * `{:error, {:unsupported_option, option}}` for unknown options.

# `metadata`

```elixir
@spec metadata() :: {:ok, map() | nil}
```

Returns the metadata map for the currently loaded kernel set, or `nil` if no
kernels have been loaded.

## Returns

  * `{:ok, map() | nil}`

# `state`

```elixir
@spec state(String.t(), float(), keyword()) :: {:ok, map()} | {:error, term()}
```

Returns the SPICE state (position, velocity, ecliptic coordinates) for a target.

`target` must be a SPICE target name string. `et` is ephemeris time in seconds
past J2000 as returned by `utc_to_et/1`. Requires kernels to be loaded.

## Options

All state options are fixed to the v0.1 defaults in this release. Passing
non-default values returns `{:error, {:unsupported_option, option}}`.

## Returns

  * `{:ok, map()}` — state map with position/velocity/ecliptic keys.
  * `{:error, :invalid_et}` when `et` is not a number.
  * `{:error, :invalid_target}` when `target` is not a binary.
  * `{:error, :kernels_not_loaded}` if no kernels have been loaded.

# `utc_to_et`

```elixir
@spec utc_to_et(DateTime.t()) :: {:ok, float()} | {:error, term()}
```

Converts a UTC `%DateTime{}` to an ephemeris time (ET) seconds-past-J2000 float.

Requires kernels to be loaded via `load_kernels/0`.

## Returns

  * `{:ok, float()}` — ET value in seconds past J2000.
  * `{:error, :invalid_datetime}` if the argument is not a `%DateTime{}`.
  * `{:error, :kernels_not_loaded}` if no kernels have been loaded.

---

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