# `Gemini.Auth.TokenCache`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L1)

ETS-based token caching with automatic expiration handling.

Provides thread-safe token caching to reduce API calls for token refresh.
Tokens are automatically considered expired based on their TTL, with a
configurable refresh buffer to ensure tokens are refreshed before expiration.

## Features

- Thread-safe ETS-based storage
- Automatic expiration handling
- Refresh buffer (default 5 minutes before expiry)
- Multiple cache key support for different credentials

## Usage

    # Initialize the cache (called automatically on application start)
    TokenCache.init()

    # Cache a token with 3600 second TTL
    TokenCache.put("my_key", "access_token_here", 3600)

    # Retrieve cached token (returns nil if expired)
    case TokenCache.get("my_key") do
      {:ok, token} -> {:ok, token}
      :error -> # Token expired or not found, refresh needed
    end

    # Invalidate a cached token
    TokenCache.invalidate("my_key")

# `cache_entry`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L43)

```elixir
@type cache_entry() :: {cache_key(), token(), expiry_time :: integer()}
```

# `cache_key`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L40)

```elixir
@type cache_key() :: String.t() | atom()
```

# `token`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L41)

```elixir
@type token() :: String.t()
```

# `ttl`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L42)

```elixir
@type ttl() :: pos_integer()
```

# `clear`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L183)

```elixir
@spec clear() :: :ok
```

Clear all cached tokens.

Removes all entries from the cache. Useful for testing or when
you need to force refresh all tokens.

## Examples

    TokenCache.clear()

# `get`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L141)

```elixir
@spec get(cache_key()) :: {:ok, token()} | :error
```

Retrieve a cached token if it exists and has not expired.

Returns `{:ok, token}` if the token is cached and still valid,
or `:error` if the token is expired or not found.

## Parameters

- `key`: The cache key used when storing the token

## Returns

- `{:ok, token}` - Token is cached and still valid
- `:error` - Token is expired, not found, or cache not initialized

## Examples

    case TokenCache.get("my_key") do
      {:ok, token} ->
        # Use the cached token
        {:ok, token}

      :error ->
        # Token expired or not found, need to refresh
        refresh_token()
    end

# `init`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L60)

```elixir
@spec init() :: :ok
```

Initialize the token cache table.

Creates an ETS table for storing tokens. This is called automatically
when the application starts, but can be called manually if needed.

Safe to call multiple times - if the table already exists, it will
not create a new one.

## Examples

    iex> Gemini.Auth.TokenCache.init()
    :ok

# `invalidate`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L165)

```elixir
@spec invalidate(cache_key()) :: :ok
```

Invalidate (remove) a cached token.

Useful when you know a token is no longer valid and want to force
a refresh on the next request.

## Parameters

- `key`: The cache key to invalidate

## Examples

    TokenCache.invalidate("my_key")

# `put`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L96)

```elixir
@spec put(cache_key(), token(), ttl(), keyword()) :: :ok
```

Cache a token with the specified time-to-live (TTL).

The token will be considered expired after `ttl` seconds, minus the
refresh buffer (default 5 minutes). This ensures tokens are refreshed
before they actually expire.

## Parameters

- `key`: Unique identifier for this token (string or atom)
- `token`: The access token to cache
- `ttl`: Time-to-live in seconds

## Options

- `:refresh_buffer` - Seconds before expiry to consider token expired
  (default: 300 seconds / 5 minutes)

## Examples

    # Cache token for 1 hour
    TokenCache.put("vertex_ai_token", "ya29.abc123", 3600)

    # Cache with custom refresh buffer (refresh 10 minutes early)
    TokenCache.put("my_token", "token123", 3600, refresh_buffer: 600)

# `stats`
[🔗](https://github.com/nshkrdotcom/gemini_ex/blob/v0.11.0/lib/gemini/auth/token_cache.ex#L208)

```elixir
@spec stats() :: %{size: non_neg_integer(), keys: [cache_key()]}
```

Get statistics about the token cache.

Returns information about the cache including number of entries
and which tokens are cached.

## Returns

Map with cache statistics:
- `:size` - Number of cached tokens
- `:keys` - List of cache keys

## Examples

    TokenCache.stats()
    #=> %{size: 2, keys: ["vertex_ai_token", "another_token"]}

---

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