defmodule Riverside.IO.Random.Sandbox do
@behaviour Riverside.IO.Random.Behaviour
require Logger
alias Riverside.IO.Random.Real
use GenServer
@type mode :: :fixture | :real
defstruct uuid: [],
hex: [],
bigint: [],
mode: :fixture
def mode(mode) do
GenServer.call(__MODULE__, {:set_mode, mode})
end
def hex(len) do
{:ok, hex} = GenServer.call(__MODULE__, {:hex, len})
Logger.debug("<Riverside.Random.Sandbox> hex/1 returns: #{hex}")
hex
end
def bigint() do
{:ok, bigint} = GenServer.call(__MODULE__, :bigint)
Logger.debug("<Riverside.Random.Sandbox> bigint/0 returns: #{bigint}")
bigint
end
def uuid() do
{:ok, uuid} = GenServer.call(__MODULE__, :uuid)
Logger.debug("<Riverside.Random.Sandbox> uuid/0 returns: #{uuid}")
uuid
end
def create_and_set_hex(len) do
hex = Real.hex(len)
set_hex(hex)
hex
end
def set_hex(list) when is_list(list) do
Logger.debug("<Riverside.Random.Sandbox> hex refreshes to #{inspect(list)}")
GenServer.call(__MODULE__, {:set_hex_list, list})
end
def set_hex(hex) do
set_hex([hex])
end
def create_and_set_bigint() do
bigint = Real.bigint()
set_bigint(bigint)
bigint
end
def set_bigint(list) when is_list(list) do
Logger.debug("<Riverside.Random.Sandbox> bigint refreshes to #{inspect(list)}")
GenServer.call(__MODULE__, {:set_bigint_list, list})
end
def set_bigint(bigint) do
set_bigint([bigint])
end
def create_and_set_uuid() do
uuid = Real.uuid()
set_uuid(uuid)
uuid
end
def set_uuid(list) when is_list(list) do
Logger.debug("<Riverside.Random.Sandbox> Random UUI refreshes to #{inspect(list)}")
GenServer.call(__MODULE__, {:set_uuid_list, list})
end
def set_uuid(uuid) do
set_uuid([uuid])
end
def start_link() do
GenServer.start_link(__MODULE__, nil, name: __MODULE__)
end
def init(_args) do
{:ok, %{hex: [], bigint: [], uuid: [], mode: :fixture}}
end
def handle_call({:set_mode, mode}, _from, state) do
{:reply, :ok, %{state | mode: mode}}
end
def handle_call({:set_hex_list, list}, _from, state) do
{:reply, :ok, %{state | hex: list}}
end
def handle_call({:set_bigint_list, list}, _from, state) do
{:reply, :ok, %{state | bigint: list}}
end
def handle_call({:set_uuid_list, list}, _from, state) do
{:reply, :ok, %{state | uuid: list}}
end
def handle_call({:hex, len}, _from, %{mode: :real} = state) do
{:reply, {:ok, Real.hex(len)}, state}
end
def handle_call({:hex, _len}, _from, %{hex: stack} = state) do
{hex, stack2} = shift_stack(stack)
{:reply, {:ok, hex}, %{state | hex: stack2}}
end
def handle_call(:bigint, _from, %{mode: :real} = state) do
{:reply, {:ok, Real.bigint()}, state}
end
def handle_call(:bigint, _from, %{bigint: stack} = state) do
{bigint, stack2} = shift_stack(stack)
{:reply, {:ok, bigint}, %{state | bigint: stack2}}
end
def handle_call(:uuid, _from, %{mode: :real} = state) do
{:reply, {:ok, Real.uuid()}, state}
end
def handle_call(:uuid, _from, %{uuid: stack} = state) do
{uuid, stack2} = shift_stack(stack)
{:reply, {:ok, uuid}, %{state | uuid: stack2}}
end
def terminate(_reason, _state) do
:ok
end
defp shift_stack([]) do
raise "<Riverside.Random.Sandbox> No more dummy data, set enough amount of them"
end
defp shift_stack([first | rest]) do
{first, rest}
end
end