defmodule Refuge.NativeLink.GRPCClientIntegrationTest do
  use ExUnit.Case, async: false
  alias Refuge.Nativelink.BuildRequest
  alias Refuge.Nativelink.BuildResponse
  alias Refuge.Nativelink.NativeLinkService.Stub
  
  @moduletag :integration
  @go_app_dir "/Users/osayame/trace/examples/go-tutorial/stage1"
  @go_app_target "//:hello"
  @server_port 1989
  
  setup do
    # The gRPC server should already be running on port 1989
    # We'll connect directly to it in our tests
    # Add a short delay to ensure server is ready
    :timer.sleep(300)
    
    # Return the endpoint info for the tests to use
    %{endpoint: "localhost:#{@server_port}"}
  end
  
  test "client can send ExecuteBuild request and receive response", %{endpoint: endpoint} do
    # Connect to the server using a standard gRPC client channel
    # Without using GRPC.Logger.Client which seems to be missing
    {:ok, channel} = GRPC.Stub.connect(endpoint)
    
    # Create the BuildRequest
    req = %BuildRequest{
      build_dir: @go_app_dir,
      target: @go_app_target
    }
    
    # Send the request to the server
    IO.puts("\nSending ExecuteBuild request to #{endpoint} for target #{@go_app_target} in #{@go_app_dir}...")
    {:ok, response} = Stub.execute_build(channel, req)
    
    # Verify response
    assert %BuildResponse{} = response
    assert response.status == 0
    
    # Log the response for verification
    IO.puts("\n----------GRPC INTEGRATION TEST RESPONSE----------")
    IO.puts("Status: #{response.status}")
    IO.puts("\nBuild Output:")
    IO.puts(response.build_output)
    
    # Check for expected output patterns
    assert String.contains?(response.build_output, "INFO: Analyzed target //:hello")
    assert String.contains?(response.build_output, "Target //:hello up-to-date:")
    assert String.contains?(response.build_output, "bazel-bin/hello_/hello")
    assert String.contains?(response.build_output, "Build completed successfully")
    
    # If run output exists, print that too
    if response.run_output && response.run_output != "" do
      IO.puts("\nRun Output:")
      IO.puts(response.run_output)
      IO.puts("-----------------------------------------------")
      
      # Verify Go app output contains expected text
      assert String.contains?(response.run_output, "Hello, Bazel")
    else
      IO.puts("\nNo run output received")
      IO.puts("-----------------------------------------------")
    end
  end
  
  test "client handles non-existent directory gracefully", %{endpoint: endpoint} do
    # Connect to the server
    {:ok, channel} = GRPC.Stub.connect(endpoint)
    
    # Create request with non-existent directory
    req = %BuildRequest{
      build_dir: "/non/existent/directory",
      target: @go_app_target
    }
    
    # Send request
    {:ok, response} = Stub.execute_build(channel, req)
    
    # Verify error response
    assert %BuildResponse{} = response
    assert response.status != 0
    assert String.contains?(response.build_output, "directory does not exist")
    
    # Log for verification
    IO.puts("\n----------NON-EXISTENT DIRECTORY TEST----------")
    IO.puts("Status: #{response.status}")
    IO.puts("Error message: #{response.build_output}")
    IO.puts("-----------------------------------------------")
  end
end
