defmodule Refuge.GRPC.EventStoreTest do
  use ExUnit.Case
  alias Refuge.GRPC.EventStore

  setup do
    # Reset the state of the EventStore between tests
    # Send a reset message to the GenServer
    :sys.replace_state(EventStore, fn _state -> %{events: [], subscribers: []} end)
    :ok
  end

  test "store_event adds an event to the store" do
    # Initially the store should be empty
    assert EventStore.list_events() == []

    # Store an event
    event_data = %{message: "Test event"}
    EventStore.store_event(:test_event, event_data)

    # Give the cast operation time to complete
    Process.sleep(100)

    # Check that the event was added
    events = EventStore.list_events()
    assert length(events) == 1
    event = List.first(events)
    assert event.type == :test_event
    assert event.data == event_data
  end

  test "list_events returns events in chronological order" do
    # Store multiple events
    EventStore.store_event(:event1, %{index: 1})
    EventStore.store_event(:event2, %{index: 2})
    EventStore.store_event(:event3, %{index: 3})

    # Give the cast operations time to complete
    Process.sleep(100)

    # Check that events are returned in reverse chronological order (newest first)
    events = EventStore.list_events()
    assert length(events) == 3
    [event3, event2, event1] = events
    assert event1.data.index == 1
    assert event2.data.index == 2
    assert event3.data.index == 3
  end

  test "subscribe and broadcast works correctly" do
    # Subscribe to events
    :ok = EventStore.subscribe()

    # Store an event, which should be broadcast to subscribers
    event_data = %{message: "Broadcasted event"}
    EventStore.store_event(:broadcasted_event, event_data)

    # Check that we receive the broadcast
    assert_receive {:broadcasted_event, ^event_data}, 1000
  end

  test "events are limited to max_events" do
    # The @max_events is set to 100 in the module
    # For testing, we'll add just a few more than that to verify the limit works
    
    # Add 105 events
    for i <- 1..105 do
      EventStore.store_event(:numbered_event, %{index: i})
    end
    
    # Give the cast operations time to complete
    Process.sleep(200)
    
    # Check that we only have 100 events (the limit) and they're the most recent ones
    events = EventStore.list_events()
    assert length(events) == 100
    
    # The newest event (105) should be first, and oldest kept should be 6
    first_event = List.first(events)
    last_event = List.last(events)
    assert first_event.data.index == 105
    assert last_event.data.index == 6
  end
end
