# `PaperTiger.Clock`
[🔗](https://github.com/EnaiaInc/paper_tiger/blob/v1.2.2/lib/paper_tiger/clock.ex#L1)

Manages time for PaperTiger. Three modes:

- `:real` - Uses System.system_time(:second)
- `:accelerated` - Real time × multiplier (1 real sec = N PaperTiger secs)
- `:manual` - Frozen time, advance via `PaperTiger.advance_time/1`

## Examples

    # Real time (production/PR apps)
    config :paper_tiger, time_mode: :real

    # Accelerated time (integration tests)
    config :paper_tiger,
      time_mode: :accelerated,
      time_multiplier: 100  # 1 real second = 100 Stripe seconds

    # Manual time (unit tests)
    config :paper_tiger, time_mode: :manual

    # Advance time in tests
    PaperTiger.advance_time(days: 30)
    PaperTiger.advance_time(seconds: 3600)

## Performance

The `now/0` function reads directly from ETS to avoid GenServer bottleneck.
Only mode changes and time advances go through the GenServer.

# `mode`

```elixir
@type mode() :: :real | :accelerated | :manual
```

# `state`

```elixir
@type state() :: %{
  mode: mode(),
  multiplier: pos_integer(),
  offset: integer(),
  started_at: integer()
}
```

# `advance`

```elixir
@spec advance(integer() | keyword()) :: :ok
```

Advances time by the given amount (manual mode only).

## Examples

    PaperTiger.Clock.advance(seconds: 3600)
    PaperTiger.Clock.advance(days: 30)
    PaperTiger.Clock.advance(86400)  # 1 day in seconds

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `get_mode`

```elixir
@spec get_mode() :: mode()
```

Returns the current clock mode.

## Examples

    PaperTiger.Clock.get_mode()
    #=> :real

# `now`

```elixir
@spec now() :: integer()
```

Returns the current PaperTiger time as Unix timestamp (seconds).

Behaves differently based on time mode:
- `:real` - Returns actual system time
- `:accelerated` - Returns system time × multiplier
- `:manual` - Returns frozen time + manual offset

This reads directly from ETS to avoid GenServer bottleneck.

# `reset`

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

Resets the clock to current system time.

Useful for cleaning up between tests.

# `set_mode`

```elixir
@spec set_mode(
  mode(),
  keyword()
) :: :ok
```

Changes the time mode dynamically.

This is useful for tests that need to switch between modes.

## Options

- `:multiplier` - Time multiplier for accelerated mode (default: 1)
- `:timestamp` - Starting timestamp for manual mode (default: current time)

# `start_link`

```elixir
@spec start_link(keyword()) :: GenServer.on_start()
```

Starts the Clock GenServer.

---

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