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

Unified chaos testing infrastructure for PaperTiger.

Consolidates all chaos testing capabilities into a single coordinator:
- Payment chaos (failure rates, decline codes)
- Event chaos (out-of-order delivery, duplicates, delays)
- API chaos (timeouts, rate limits, server errors)

## Configuration

    PaperTiger.ChaosCoordinator.configure(%{
      payment: %{
        failure_rate: 0.1,
        decline_codes: [:card_declined, :insufficient_funds],
        decline_weights: %{card_declined: 0.7, insufficient_funds: 0.3}
      },
      events: %{
        out_of_order: true,
        duplicate_rate: 0.05,
        buffer_window_ms: 500
      },
      api: %{
        timeout_rate: 0.02,
        timeout_ms: 5000,
        rate_limit_rate: 0.01,
        error_rate: 0.01
      }
    })

## Per-Customer Overrides

    # Force specific customer to always fail
    PaperTiger.ChaosCoordinator.simulate_failure("cus_xxx", :card_declined)

    # Clear override
    PaperTiger.ChaosCoordinator.clear_simulation("cus_xxx")

## Namespace Isolation

Uses ETS with namespace isolation for test concurrency.
Each test process can have its own chaos state.

# `all_decline_codes`

Returns all available decline codes.

# `child_spec`

Returns a specification to start this module under a supervisor.

See `Supervisor`.

# `cleanup`

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

Cleans up after chaos testing.

This resets chaos configuration AND flushes all Paper Tiger stores to remove
any test data that was created during chaos testing. Call this after chaos
testing to prevent test data from being synced to the host application's
database.

## Example

    # After running chaos tests
    PaperTiger.ChaosCoordinator.cleanup()

# `clear_simulation`

```elixir
@spec clear_simulation(String.t()) :: :ok
```

Clears any payment simulation for a customer.

# `configure`

```elixir
@spec configure(map()) :: :ok
```

Configures chaos settings. Merges with existing config.

## Examples

    # Enable payment chaos
    configure(%{payment: %{failure_rate: 0.1}})

    # Enable event chaos
    configure(%{events: %{out_of_order: true, buffer_window_ms: 500}})

    # Enable API chaos
    configure(%{api: %{timeout_rate: 0.05}})

# `default_decline_codes`

Returns the default decline codes.

# `flush_events`

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

Forces all buffered events to be delivered immediately.

Useful in tests to ensure events are processed before assertions.

# `get_config`

```elixir
@spec get_config() :: map()
```

Gets the current chaos configuration.

# `get_stats`

```elixir
@spec get_stats() :: map()
```

Gets chaos statistics.

# `queue_event`

```elixir
@spec queue_event(map(), function()) :: :ok
```

Queues an event for potential chaos processing.

If event chaos is configured, the event may be:
- Buffered and delivered out of order
- Duplicated
- Delayed

If no event chaos is configured, delivers immediately.

# `reset`

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

Resets all chaos configuration to defaults and clears all state.

# `should_api_fail?`

```elixir
@spec should_api_fail?(String.t()) ::
  :ok
  | {:timeout, non_neg_integer()}
  | :rate_limit
  | :server_error
  | {:custom_response, pos_integer(), map()}
```

Determines if an API request should fail or return a custom response.

Returns:
- `:ok` - Request should proceed normally
- `{:timeout, ms}` - Request should timeout after sleeping
- `:rate_limit` - Request should return 429
- `:server_error` - Request should return 500/502/503
- `{:custom_response, status, body}` - Return a custom JSON response

## Custom Response Example

    PaperTiger.ChaosCoordinator.configure(%{
      api: %{
        endpoint_overrides: %{
          "/v1/subscriptions" => {:custom_response, 200, %{"id" => "sub_1", "status" => "past_due"}}
        }
      }
    })

# `should_payment_fail?`

```elixir
@spec should_payment_fail?(String.t()) :: {:ok, :succeed} | {:ok, {:fail, atom()}}
```

Determines if a payment should fail for the given customer.

Checks customer overrides first, then applies configured chaos rules.

Returns:
- `{:ok, :succeed}` - Payment should succeed
- `{:ok, {:fail, decline_code}}` - Payment should fail with the given code

# `simulate_failure`

```elixir
@spec simulate_failure(String.t(), atom()) :: :ok
```

Forces payment failures for a specific customer.

The customer's payments will fail with the given decline code until cleared.

# `start_link`

Starts the ChaosCoordinator.

---

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