  # GenServer for dispatching trait_call messages from Rust.
  defmodule {{ server_module }} do
    use GenServer

    def start_link(state) do
      GenServer.start_link(__MODULE__, state)
    end

    def init(state) do
      {:ok, state}
    end

    def handle_cast({:trait_call, method, args, reply_id}, registrations) do
      # args arrives as a native Erlang map (no JSON decode); dispatch to the registered handler.
      case decode_args_and_dispatch(method, args, registrations) do
        {:ok, response} ->
          Native.complete_trait_call(reply_id, response)

        {:error, reason} ->
          error_response = %{"error" => reason}
          Native.complete_trait_call(reply_id, error_response)
      end

      {:noreply, registrations}
    end


    defp decode_args_and_dispatch(method, args, registrations) do
      # Find handler entry for the method
      case find_handler(method, registrations) do
        nil ->
          {:error, "Handler not registered for method: #{method}"}

        {^method, _metadata, handler} ->
          # Call the registered handler with the native args map (assumes handler accepts a single arg)
          try do
            response = handler.(args)
            # Encode response to JSON (the reply path stays JSON)
            case Jason.encode(response) do
              {:ok, response_json} ->
                {:ok, response_json}

              {:error, reason} ->
                {:error, "Failed to encode response: #{reason}"}
            end
          rescue
            e ->
              {:error, "Handler raised exception: #{inspect(e)}"}
          end
      end
    end

    defp find_handler(_method, []), do: nil

    defp find_handler(target, [{name, _metadata, _handler} = entry | _rest]) when name == target do
      entry
    end

    defp find_handler(target, [_head | rest]) do
      find_handler(target, rest)
    end
  end
