defmodule LogMock do use GenServer defstruct [:pid, :last_update] alias __MODULE__, as: State alias TeslaMate.Log.{Drive, ChargingProcess, Update, Car, Position} alias TeslaMate.Log # API def start_link(opts) do GenServer.start_link(__MODULE__, opts, name: Keyword.fetch!(opts, :name)) end def start_state(name, car, state, opts) do GenServer.call(name, {:start_state, car, state, opts}) end def get_current_state(name, car), do: GenServer.call(name, {:get_current_state, car}) def start_drive(name, car), do: GenServer.call(name, {:start_drive, car}) def close_drive(name, drive, opts \\ []), do: GenServer.call(name, {:close_drive, drive, opts}) def start_update(name, car, opts), do: GenServer.call(name, {:start_update, car, opts}) def cancel_update(name, update), do: GenServer.call(name, {:cancel_update, update}) def finish_update(name, update, vsn, opts) do GenServer.call(name, {:finish_update, update, vsn, opts}) end def get_latest_update(name, car) do GenServer.call(name, {:get_latest_update, car}) end def insert_missed_update(name, car, vsn, opts) do GenServer.call(name, {:insert_missed_update, car, vsn, opts}) end def start_charging_process(name, car, position_attrs, opts \\ []) do GenServer.call(name, {:start_charging_process, car, position_attrs, opts}) end def complete_charging_process(name, cproc) do GenServer.call(name, {:complete_charging_process, cproc}) end def insert_position(name, car_or_drive, attrs) do GenServer.call(name, {:insert_position, car_or_drive, attrs}) end def insert_charge(name, cproc, attrs) do GenServer.call(name, {:insert_charge, cproc, attrs}) end def get_positions_without_elevation(name, min_id, opts) do GenServer.call(name, {:get_positions_without_elevation, min_id, opts}) end def update_car(name, car, attrs, opts) do GenServer.call(name, {:update_car, car, attrs, opts}) end def get_latest_position(name, car) do GenServer.call(name, {:get_latest_position, car}) end # Callbacks @impl true def init(opts) do state = %State{ pid: Keyword.fetch!(opts, :pid), last_update: Keyword.fetch!(opts, :last_update) } {:ok, state} end @impl true def handle_call({:start_state, _car, s, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Log.State{state: s, start_date: DateTime.utc_now()}}, state} end def handle_call({:get_current_state, _}, _from, state) do {:reply, {:ok, %Log.State{state: :online, start_date: DateTime.from_unix!(0)}}, state} end def handle_call({:insert_position, _, attrs} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, struct!(Log.Position, attrs)}, state} end def handle_call({:insert_charge, _, _attrs} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Log.Charge{id: 222}}, state} end def handle_call({:start_charging_process, _, _, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %ChargingProcess{id: 99, start_date: DateTime.utc_now()}}, state} end def handle_call({:complete_charging_process, cproc} = action, _from, %State{} = state) do send(state.pid, action) new_cproc = %ChargingProcess{cproc | charge_energy_added: 45, end_date: DateTime.utc_now()} {:reply, {:ok, new_cproc}, state} end def handle_call({:start_drive, _car} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Drive{id: 111}}, state} end def handle_call({:close_drive, _drive, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Drive{duration_min: 10, distance: 20.0}}, state} end def handle_call({:start_update, _car, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Update{id: 111}}, state} end def handle_call({:cancel_update, _update} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Update{}}, state} end def handle_call({:finish_update, _, _, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Update{}}, state} end def handle_call({:get_latest_update, _car}, _from, %State{last_update: update} = state) do {:reply, update, state} end def handle_call({:insert_missed_update, _, _, _} = action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, {:ok, %Update{}}, state} end def handle_call({:get_positions_without_elevation, min_id, _opts}, _from, state) do send(state.pid, {:get_positions_without_elevation, min_id}) {:reply, {[], nil}, state} end def handle_call({:update_car, car, attrs, _opts} = _action, _from, %State{pid: _pid} = state) do result = car |> Car.changeset(attrs) |> Ecto.Changeset.apply_changes() {:reply, {:ok, result}, state} end def handle_call({:get_latest_position, _car}, _from, state) do {:reply, %Position{latitude: 0.0, longitude: 0.0}, state} end def handle_call(action, _from, %State{pid: pid} = state) do send(pid, action) {:reply, :ok, state} end end