defmodule KafkaEx.New.Adapter.LeaveGroupTest do
  use ExUnit.Case, async: true

  alias KafkaEx.New.Adapter
  alias KafkaEx.Protocol.LeaveGroup.Request, as: LeaveGroupRequest
  alias KafkaEx.Protocol.LeaveGroup.Response, as: LeaveGroupResponse
  alias Kayrock.LeaveGroup

  describe "leave_group_request/1 - legacy to new API" do
    test "converts legacy LeaveGroupRequest to Kayrock V0 request" do
      legacy_request = %LeaveGroupRequest{
        group_name: "test-group",
        member_id: "consumer-123"
      }

      {kayrock_request, consumer_group} = Adapter.leave_group_request(legacy_request)

      assert consumer_group == "test-group"

      assert kayrock_request == %LeaveGroup.V0.Request{
               group_id: "test-group",
               member_id: "consumer-123"
             }
    end

    test "handles empty member_id" do
      legacy_request = %LeaveGroupRequest{
        group_name: "my-group",
        member_id: ""
      }

      {kayrock_request, consumer_group} = Adapter.leave_group_request(legacy_request)

      assert consumer_group == "my-group"
      assert kayrock_request.member_id == ""
    end

    test "handles unicode characters in group_name and member_id" do
      legacy_request = %LeaveGroupRequest{
        group_name: "group-日本",
        member_id: "member-한국"
      }

      {kayrock_request, consumer_group} = Adapter.leave_group_request(legacy_request)

      assert consumer_group == "group-日本"
      assert kayrock_request.group_id == "group-日本"
      assert kayrock_request.member_id == "member-한국"
    end

    test "handles long string values" do
      long_group = String.duplicate("a", 500)
      long_member = String.duplicate("b", 500)

      legacy_request = %LeaveGroupRequest{
        group_name: long_group,
        member_id: long_member
      }

      {kayrock_request, consumer_group} = Adapter.leave_group_request(legacy_request)

      assert consumer_group == long_group
      assert kayrock_request.group_id == long_group
      assert kayrock_request.member_id == long_member
    end
  end

  describe "leave_group_response/1 - new to legacy API (V0)" do
    test "converts successful V0 response to legacy format" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 0
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :no_error} = legacy_response
    end

    test "converts V0 error response (unknown_member_id)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 25
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :unknown_member_id} = legacy_response
    end

    test "converts V0 error response (group_id_not_found)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 69
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :group_id_not_found} = legacy_response
    end

    test "converts V0 error response (rebalance_in_progress)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 27
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :rebalance_in_progress} = legacy_response
    end

    test "converts V0 error response (not_coordinator)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 16
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :not_coordinator} = legacy_response
    end

    test "converts V0 error response (coordinator_not_available)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 15
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :coordinator_not_available} = legacy_response
    end

    test "converts V0 error response (group_authorization_failed)" do
      kayrock_response = %LeaveGroup.V0.Response{
        error_code: 30
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :group_authorization_failed} = legacy_response
    end
  end

  describe "leave_group_response/1 - new to legacy API (V1)" do
    test "converts successful V1 response to legacy format (ignores throttle_time_ms)" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 0,
        throttle_time_ms: 100
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :no_error} = legacy_response
    end

    test "converts V1 response with zero throttle_time_ms" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 0,
        throttle_time_ms: 0
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :no_error} = legacy_response
    end

    test "converts V1 error response (unknown_member_id) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 25,
        throttle_time_ms: 50
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :unknown_member_id} = legacy_response
    end

    test "converts V1 error response (group_id_not_found) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 69,
        throttle_time_ms: 75
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :group_id_not_found} = legacy_response
    end

    test "converts V1 error response (rebalance_in_progress) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 27,
        throttle_time_ms: 200
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :rebalance_in_progress} = legacy_response
    end

    test "converts V1 error response (not_coordinator) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 16,
        throttle_time_ms: 10
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :not_coordinator} = legacy_response
    end

    test "converts V1 error response (coordinator_not_available) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 15,
        throttle_time_ms: 25
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :coordinator_not_available} = legacy_response
    end

    test "converts V1 error response (group_authorization_failed) with throttle" do
      kayrock_response = %LeaveGroup.V1.Response{
        error_code: 30,
        throttle_time_ms: 30
      }

      legacy_response = Adapter.leave_group_response(kayrock_response)

      assert %LeaveGroupResponse{error_code: :group_authorization_failed} = legacy_response
    end
  end

  describe "round-trip conversion" do
    test "legacy request -> kayrock -> legacy response maintains structure" do
      # Start with legacy request
      legacy_request = %LeaveGroupRequest{
        group_name: "test-group",
        member_id: "member-1"
      }

      # Convert to Kayrock format
      {kayrock_request, consumer_group} = Adapter.leave_group_request(legacy_request)

      # Verify conversion
      assert consumer_group == "test-group"
      assert kayrock_request.group_id == "test-group"
      assert kayrock_request.member_id == "member-1"

      # Simulate successful Kayrock response (V0)
      kayrock_response_v0 = %LeaveGroup.V0.Response{error_code: 0}

      # Convert back to legacy
      legacy_response = Adapter.leave_group_response(kayrock_response_v0)

      assert %LeaveGroupResponse{error_code: :no_error} = legacy_response
    end

    test "legacy request -> kayrock V1 -> legacy response maintains error semantics" do
      # Start with legacy request
      legacy_request = %LeaveGroupRequest{
        group_name: "test-group",
        member_id: "member-1"
      }

      # Convert to Kayrock format (would be V0 request)
      {_kayrock_request, _consumer_group} = Adapter.leave_group_request(legacy_request)

      # Simulate error Kayrock response (V1 with throttle)
      kayrock_response_v1 = %LeaveGroup.V1.Response{
        error_code: 27,
        throttle_time_ms: 150
      }

      # Convert back to legacy
      legacy_response = Adapter.leave_group_response(kayrock_response_v1)

      # Verify error code is preserved (throttle is ignored in legacy)
      assert %LeaveGroupResponse{error_code: :rebalance_in_progress} = legacy_response
    end
  end
end
