defmodule RefugeWeb.InvocationLiveTest do
  use RefugeWeb.ConnCase, async: false

  import Phoenix.LiveViewTest

  alias Refuge.{Nativelink.BuildRequest, Nativelink.BuildResponse, NativeLink.GRPCServer}
  # EventStore is not used in this test
  # alias Refuge.GRPC.EventStore

  @go_app_dir "/Users/osayame/trace/examples/go-tutorial/stage3"
  @go_app_target "//..."

  test "execute build then view invocation", %{conn: conn} do
    # # Subscribe to event store
    # :ok = EventStore.subscribe()

    # # Store initial build ID
    # test_build_id = "test-build-id-#{:rand.uniform(1000)}"

    # # Simulate a build event with a build_id
    # EventStore.store_event(:build_event, %{
    #   "stream_id" => %{"build_id" => test_build_id},
    #   "event" => "Build started"
    # })

    # Create a BuildRequest for the Go app example
    req = %BuildRequest{
      build_dir: @go_app_dir,
      target: @go_app_target
    }

    # Call the ExecuteBuild function directly (bypassing gRPC client)
    result = GRPCServer.execute_build(req, nil)

    # Assert the response is successful
    assert %BuildResponse{} = result
    # status 0 means success
    assert result.status == 0

    # Print the key build output for verification
    IO.puts("\n--------- BUILD TEST OUTPUT----------")

    # Extract and print the build ID using regex
    build_id_regex = ~r/Invocation ID: ([\w-]+)/
    
    # Initialize test_build_id
    test_build_id = case Regex.run(build_id_regex, result.build_output) do
      [full_match, build_id] ->
        IO.puts(full_match)
        build_id

      _ ->
        IO.puts("Could not extract build ID from output, printing full output:")
        IO.puts(result.build_output)
        "unknown-build-id"
    end

    # Now visit the LiveView for that invocation
    {:ok, view, html} = live(conn, "/invocation/#{test_build_id}")

    # Page should show the invocation id
    assert html =~ test_build_id

    # Verify the LiveView is showing events for this invocation
    assert wait_for_condition(
             fn ->
               html = render(view)
               html =~ test_build_id
             end,
             5000
           )
  end

  # Helper function to poll for a condition with timeout
  defp wait_for_condition(condition_fn, timeout, interval \\ 100) do
    start_time = System.monotonic_time(:millisecond)
    do_wait_for_condition(condition_fn, start_time, timeout, interval)
  end

  defp do_wait_for_condition(condition_fn, start_time, timeout, interval) do
    if condition_fn.() do
      true
    else
      current_time = System.monotonic_time(:millisecond)
      elapsed = current_time - start_time

      if elapsed > timeout do
        false
      else
        :timer.sleep(interval)
        do_wait_for_condition(condition_fn, start_time, timeout, interval)
      end
    end
  end
end
