package common

import (
	"encoding/json"
	"testing"
	"time"

	"github.com/fiskerinc/cloud-services/pkg/grpc/kafka_grpc"
	"github.com/fiskerinc/cloud-services/pkg/utils/elptr"
)

func TestDepotRouteHMIPayload(t *testing.T) {
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_DepotPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'init' handler",
			payload: &kafka_grpc.GRPC_DepotPayload{
				Handler: "init",
				Data: &kafka_grpc.GRPC_DepotPayload_HmiSession{
					HmiSession: &kafka_grpc.HMISessionData{
						SessionId: "123456",
						Vin:       "ABC123",
						Salt:      "salt123",
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "init",
				Data: func() []byte {
					data, _ := json.Marshal(&HMISessionData{
						SessionID: "123456",
						VIN:       "ABC123",
						Salt:      "salt123",
					})
					return data
				}(),
			},
			expectedError: nil,
		},
		// Add more test cases as needed
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := DepotRouteHMIPayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestDepotRouteTRexPayloadMessage(t *testing.T) {
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_DepotPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'init' handler",
			payload: &kafka_grpc.GRPC_DepotPayload{
				Handler: "init",
				Data: &kafka_grpc.GRPC_DepotPayload_InitPayload{
					InitPayload: &kafka_grpc.InitPayload{
						Data: map[string]string{
							"key1": "value1",
							"key2": "value2",
						},
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "init",
				Data: func() []byte {
					data, _ := json.Marshal(map[string]string{
						"key1": "value1",
						"key2": "value2",
					})
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_DepotPayload{
				Handler: "init",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "init",
				Data:    nil,
			},
			expectedError: nil,
		},

		{
			name: "Invalid handlerl handler",
			payload: &kafka_grpc.GRPC_DepotPayload{
				Handler: "fake_handler",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "fake_handler",
				Data:    nil,
			},
			expectedError: nil,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := DepotRouteTRexPayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestAttendantRouteMobilePayload(t *testing.T) {
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_AttendantPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'update_approve' handler",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "update_approve",
				Data: &kafka_grpc.GRPC_AttendantPayload_UpdateApprove{
					UpdateApprove: &kafka_grpc.UpdateData{
						Id: 123,
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "update_approve",
				Data: func() []byte {
					data, _ := json.Marshal(map[string]int{"id": 123})
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Valid payload with 'updates_get' handler",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "updates_get",
				Data: &kafka_grpc.GRPC_AttendantPayload_UpdateGet{
					UpdateGet: &kafka_grpc.VehicleData{
						Vin: "ABC123",
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "updates_get",
				Data: func() []byte {
					data, _ := json.Marshal(map[string]string{"vin": "ABC123"})
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "update_approve",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "update_approve",
				Data:    nil,
			},
			expectedError: nil,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := AttendantRouteMobilePayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestUpdateManifestToGRPC(t *testing.T) {
	pub1 := "9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5b"
	pub2 := "407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85d"
	priv1 := "9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5c"
	var pub1B BinaryHex = []byte(pub1)
	var pub2B BinaryHex = []byte(pub2)
	var priv1B BinaryHex = []byte(priv1)
	date := time.Date(2022, 5, 27, 12, 49, 0, 0, time.UTC)
	unixMillis := date.UnixMilli()
	toDate := time.Unix(0, unixMillis*int64(time.Millisecond))
	flag := true
	expectedUpdate := &UpdateManifest{
		ID: 1,
		ECUs: []*UpdateManifestECU{
			{
				ID:   3,
				Mode: "v",
				ECCKeys: &ECCKeys{
					ECU:      "ecu",
					Env:      "env",
					PubKey1:  &pub1B,
					PrivKey1: &priv1B,
					PubKey2:  &pub2B,
				},
				Files: []*UpdateManifestFile{
					{
						FileID:              "file_id_value",
						UpdateManifestECUID: 123456789,
						Filename:            "filename_value",
						URL:                 "url_value",
						FileSize:            1024, // Example file size
						Checksum:            "checksum_value",
						FileType:            "type_value",
						FileOrder:           1, // Example order
						WriteRegion: MemoryRegion{
							Offset: 1024, // Example offset
							Length: 2048, // Example length
						},
						EraseRegion: &MemoryRegion{
							Offset: 4096, // Example offset
							Length: 8192, // Example length
						},
						FileKey: &FileKeyResponse{
							FileID: "file_key_file_id_value",
							Key:    "file_key_key_value",
							Auth:   "file_key_auth_value",
							Nonce:  "file_key_nonce_value",
							Error:  "file_key_error_value",
						},
						Parsed:    &flag, // Example parsed file value
						Signature: "signature_value",
						CompatibleTrims: []CompatibleTrim{
							EXTREME,
							SPORT,
						},
						CompatibleDriveSides: []CompatibleDriveSide{
							LEFT_HAND_DRIVE,
							RIGHT_HAND_DRIVE,
						},
					},
				},
			},
		},
	}

	expectedUpdate.CreatedAt = &toDate
	expectedUpdate.ECUs[0].CreatedAt = &toDate
	expectedUpdate.ECUs[0].UpdatedAt = &toDate
	expectedUpdate.ECUs[0].Files[0].CreatedAt = &date
	expectedUpdate.ECUs[0].Files[0].UpdatedAt = &date

	b, _ := json.Marshal(expectedUpdate)
	msg := MessageRawJSON{
		Handler: "send_manifest",
		Data:    b,
	}

	grpcRep := UpdateManifestToGRPC(msg)

	if grpcRep == nil {
		t.Errorf("Expected not nil reponse from UpdateManifestToGRPC but got: nil")
	}

	if grpcRep.GetHandler() != msg.Handler {
		t.Errorf("Expected handler should equal to %v but got %v:", msg.Handler, grpcRep.Handler)
	}

	reveseGRPC := GRPCToUpdateManifest(grpcRep)

	grpcP, _ := json.Marshal(reveseGRPC)

	if string(grpcP) != string(b) {
		t.Errorf("Expected data should equal to %v but got %v:", string(b), string(grpcP))
	}

}
func TestAttendantSendManifest(t *testing.T) {
	pub1 := "9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5b"
	pub2 := "407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85d"
	priv1 := "9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5c"
	var pub1B BinaryHex = []byte(pub1)
	var pub2B BinaryHex = []byte(pub2)
	var priv1B BinaryHex = []byte(priv1)
	date := time.Date(2022, 5, 27, 12, 49, 0, 0, time.UTC)
	dateString := "2022-05-27T12:49:00Z"
	unixMillis := date.UnixMilli()
	toDate := time.Unix(0, unixMillis*int64(time.Millisecond))
	flag := true
	expectedUpdate := &UpdateManifest{
		ID: 1,
		ECUs: []*UpdateManifestECU{
			{
				ID:   3,
				Mode: "v",
				ECCKeys: &ECCKeys{
					ECU:      "ecu",
					Env:      "env",
					PubKey1:  &pub1B,
					PrivKey1: &priv1B,
					PubKey2:  &pub2B,
				},
				Files: []*UpdateManifestFile{
					{
						FileID:              "file_id_value",
						UpdateManifestECUID: 123456789,
						Filename:            "filename_value",
						URL:                 "url_value",
						FileSize:            1024, // Example file size
						Checksum:            "checksum_value",
						FileType:            "type_value",
						FileOrder:           1, // Example order
						WriteRegion: MemoryRegion{
							Offset: 1024, // Example offset
							Length: 2048, // Example length
						},
						EraseRegion: &MemoryRegion{
							Offset: 4096, // Example offset
							Length: 8192, // Example length
						},
						FileKey: &FileKeyResponse{
							FileID: "file_key_file_id_value",
							Key:    "file_key_key_value",
							Auth:   "file_key_auth_value",
							Nonce:  "file_key_nonce_value",
							Error:  "file_key_error_value",
						},
						Parsed:    &flag, // Example parsed file value
						Signature: "signature_value",
						CompatibleTrims: []CompatibleTrim{
							EXTREME,
							SPORT,
						},
						CompatibleDriveSides: []CompatibleDriveSide{
							LEFT_HAND_DRIVE,
							RIGHT_HAND_DRIVE,
						},
					},
				},
			},
		},
	}

	expectedUpdate.CreatedAt = &toDate
	expectedUpdate.ECUs[0].CreatedAt = &toDate
	expectedUpdate.ECUs[0].UpdatedAt = &toDate
	expectedUpdate.ECUs[0].Files[0].CreatedAt = &date
	expectedUpdate.ECUs[0].Files[0].UpdatedAt = &date

	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_AttendantPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'send_manifest' handler",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "send_manifest",
				Data: &kafka_grpc.GRPC_AttendantPayload_UpdateManifest{
					UpdateManifest: &kafka_grpc.UpdateManifest{
						Id: 1,
						EcuUpdates: []*kafka_grpc.UpdateManifestECU{
							{
								Created: &unixMillis,
								Updated: &unixMillis,
								Id:      3,
								Mode:    "v",
								EccKeys: &kafka_grpc.ECCKey{
									Ecu: "ecu",
									Env: "env",
									PubKeyLevel_1: &kafka_grpc.BineryHex{
										Data: []byte(pub1),
									},
									Level_1: &kafka_grpc.BineryHex{
										Data: []byte(priv1),
									},
									PubKeyLevel_2: &kafka_grpc.BineryHex{
										Data: []byte(pub2),
									},
								},
								Files: []*kafka_grpc.UpdateManifestFile{
									{
										FileId:        "file_id_value",
										ManifestEcuId: 123456789,
										Filename:      "filename_value",
										Url:           "url_value",
										FileSize:      1024, // Example file size
										Checksum:      "checksum_value",
										Type:          "type_value",
										Order:         1, // Example order
										WriteRegion: &kafka_grpc.MemoryRegion{
											Offset: 1024, // Example offset
											Length: 2048, // Example length
										},
										EraseRegion: &kafka_grpc.MemoryRegion{
											Offset: 4096, // Example offset
											Length: 8192, // Example length
										},
										FileKey: &kafka_grpc.FileKeyResponse{
											FileId: "file_key_file_id_value",
											Key:    "file_key_key_value",
											Auth:   "file_key_auth_value",
											Nonce:  "file_key_nonce_value",
											Error:  "file_key_error_value",
										},
										Updated:    &dateString,
										Created:    &dateString,
										ParsedFile: &flag, // Example parsed file value
										Signature:  "signature_value",
										CompatibleTrims: []string{
											string(EXTREME),
											string(SPORT),
										},
										CompatibleDriveSides: []string{
											string(LEFT_HAND_DRIVE),
											string(RIGHT_HAND_DRIVE),
										},
									},
								},
							},
						},
						Created: &unixMillis,
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "send_manifest",
				Data: func() []byte {
					data, _ := json.Marshal(expectedUpdate)
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "send_manifest",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "send_manifest",
				Data:    nil,
			},
			expectedError: nil,
		},
		// Add more test cases as needed
	}

	// Set date

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := AttendantRouteServicePayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, <<><><<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n<<<<<got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestAttendantOrderUpdated(t *testing.T) {
	date := time.Date(2022, 5, 27, 12, 49, 0, 0, time.UTC)
	unixMillis := date.UnixMilli()
	toDate := time.Unix(0, unixMillis*int64(time.Millisecond))
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_AttendantPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'order_updated' handler",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "order_updated",
				Data: &kafka_grpc.GRPC_AttendantPayload_Order{
					Order: &kafka_grpc.Order{
						OrderNo:       123,
						MsgIdentifier: "msg123",
						SpecId:        456,
						VehicleSpecification: &kafka_grpc.VehicleSpecification{
							DestCon:   "DestinationCountry",
							FOrderId:  "FleetOrderIndicator",
							MfPlant:   "ManufacturingPlant",
							ModelType: "ModelType",
							ModelYear: 2022,
							ModelId:   1,
							OrderId:   "OrderIndicator",
							ProductId: "ProductionPhaseIndicator",
							Sn:        "SequenceNumber",
							VehicleId: "VehicleIndicator",
							Model:     "VehicleModel",
							VinPre:    "VinPrefix",
							Version:   1,
							Date:      unixMillis,
							Feature: []*kafka_grpc.FeatureCodes{
								{
									FamilyCode:  "family1",
									FeatureCode: "feature1",
								},
								{
									FamilyCode:  "family2",
									FeatureCode: "feature2",
								},
							},
						},
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "order_updated",
				Data: func() []byte {
					order := &VehicleOrder{
						OrderNumber:       123,
						MessageIdentifier: "msg123",
						SpecID:            456,
						VehicleSpecification: VehicleSpecification{
							DestinationCountry:       "DestinationCountry",
							FleetOrderIndicator:      "FleetOrderIndicator",
							ManufacturingPlant:       "ManufacturingPlant",
							ModelType:                "ModelType",
							ModelYear:                2022,
							ModelYearIndicator:       1,
							OrderIndicator:           "OrderIndicator",
							ProductionPhaseIndicator: "ProductionPhaseIndicator",
							SequenceNumber:           "SequenceNumber",
							VehicleIndicator:         "VehicleIndicator",
							VehicleModel:             "VehicleModel",
							VinPrefix:                "VinPrefix",
							VersionDuringModelYear:   1,
							ExpectedReferenceDate:    ExpectedReferenceDate{toDate},
							VehicleFeatures: []FeatureCodes{
								{
									FamilyCode:  "family1",
									FeatureCode: "feature1",
								},
								{
									FamilyCode:  "family2",
									FeatureCode: "feature2",
								},
							},
						},
					}
					data, _ := json.Marshal(order)
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_AttendantPayload{
				Handler: "order_updated",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "order_updated",
				Data:    nil,
			},
			expectedError: nil,
		},
		// Add more test cases as needed
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := AttendantRouteServicePayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestValetRouteTRexCMDChangedPayload(t *testing.T) {
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_ValetPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'charging_command' handler",
			payload: &kafka_grpc.GRPC_ValetPayload{
				Handler: "charging_command",
				Data: &kafka_grpc.GRPC_ValetPayload_ChCMD{
					ChCMD: &kafka_grpc.ChargingCommand{
						Action: "start_charging",
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "charging_command",
				Data: func() []byte {
					data, _ := json.Marshal(&kafka_grpc.ChargingCommand{
						Action: "start_charging",
					})
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_ValetPayload{
				Handler: "charging_command",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "charging_command",
				Data:    nil,
			},
			expectedError: nil,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := ValetRouteTRexPayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

func TestValetRouteTRexDepartureSchedulePayload(t *testing.T) {
	tests := []struct {
		name           string
		payload        *kafka_grpc.GRPC_ValetPayload
		expectedResult *ConsumerPayload
		expectedError  error
	}{
		{
			name: "Valid payload with 'departure_schedule' handler",
			payload: &kafka_grpc.GRPC_ValetPayload{
				Handler: "departure_schedule",
				Data: &kafka_grpc.GRPC_ValetPayload_DepartureSchedule{
					DepartureSchedule: &kafka_grpc.DepartureSchedule{
						NextDayDeparture: nil,
						DepartureDays: []*kafka_grpc.DepartureDay{
							{
								DayOfWeek: "Monday",
								Time:      "08:00",
							},
							{
								DayOfWeek: "Wednesday",
								Time:      "10:00",
							},
						},
					},
				},
			},
			expectedResult: &ConsumerPayload{
				Handler: "departure_schedule",
				Data: func() []byte {
					data, _ := json.Marshal(&DepartureSchedule{
						NextDayDeparture: nil,
						DepartureDays: []DepartureDay{
							{
								DayOfWeek: "Monday",
								Time:      "08:00",
							},
							{
								DayOfWeek: "Wednesday",
								Time:      "10:00",
							},
						},
					})
					return data
				}(),
			},
			expectedError: nil,
		},
		{
			name: "Payload with nil data",
			payload: &kafka_grpc.GRPC_ValetPayload{
				Handler: "departure_schedule",
				Data:    nil,
			},
			expectedResult: &ConsumerPayload{
				Handler: "departure_schedule",
				Data:    nil,
			},
			expectedError: nil,
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			result, err := ValetRouteTRexPayload(test.payload)

			if err != test.expectedError {
				t.Errorf("Expected error: %v, got: %v", test.expectedError, err)
			}

			if result.Handler != test.expectedResult.Handler {
				t.Errorf("Handler mismatch. Expected: %s, got: %s", test.expectedResult.Handler, result.Handler)
			}

			if string(result.Data) != string(test.expectedResult.Data) {
				t.Errorf("Data mismatch. Expected: %s, got: %s", test.expectedResult.Data, result.Data)
			}
		})
	}
}

// Unit tests for CarStateToGRPC function
func TestCarStateToGRPC(t *testing.T) {
	// Test case 1: Valid input
	ecu := CarECU{
		VIN:        "123456",
		ECU:        "ECU1",
		Version:    "v1",
		Epoch_usec: time.Now().Unix(),
	}
	carState := CarStateUpdate{
		ECUs: map[string]CarECU{"ecu1": ecu},
	}
	data, err := json.Marshal(carState)
	if err != nil {
		t.Fatalf("Failed to marshal test data: %v", err)
	}
	input1 := MessageRawJSON{
		Handler: "car_state_updated",
		Data:    data,
	}
	expected := &kafka_grpc.GRPC_AttendantPayload{
		Handler: "car_state_updated",
		Data: &kafka_grpc.GRPC_AttendantPayload_CarUpdateStatus{
			CarUpdateStatus: &kafka_grpc.CarUpdateStatus{
				Ecus: map[string]*kafka_grpc.CarECU{
					"ecu1": {
						Vin:       ecu.VIN,
						Ecu:       ecu.ECU,
						SwVersion: ecu.Version,
						EpochUsec: ecu.Epoch_usec,
						// Add other fields here as needed
					},
				},
			},
		},
	}
	output := CarStateToGRPC(input1)
	expectedJSON, _ := json.Marshal(expected)
	actualJSON, _ := json.Marshal(output)
	if string(expectedJSON) != string(actualJSON) {
		t.Errorf("Test case 1 failed: expected handler %+v, got %+v", expected.Data, output.Data)
	}
}

// func TestGRPCToECCKeys(t *testing.T) {

// 	var pub1, pub2, priv1, priv2 []byte
// 	pub1 = []byte(`9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5b`)
// 	pub2 = []byte(`9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5c`)
// 	priv1 = []byte(`407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85b`)
// 	priv2 = []byte(`407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85c`)

// 	var pub11, pub22, priv11, priv22 BinaryHex
// 	pub11 = []byte(`9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5b`)
// 	pub22 = []byte(`9a1a6949d7f8a511df6e2e2771e444dbd6de97e7d98bdecbb5adc4b8965ce3bef353f523dbea123d7882dc043d415cda02810bad1b6f1b8c6202234a424b7d5c`)
// 	priv11 = []byte(`407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85b`)
// 	priv22 = []byte(`407f59557fb64ae98bc30b5370fab138f4827e14784d79bcf707dbe35ba2b85c`)

// 	testCases := []struct {
// 		name     string
// 		payload  *kafka_grpc.GRPC_AttendantPayload
// 		expected []ECCKeys
// 	}{
// 		{
// 			name: "NilPayload",
// 			payload: &kafka_grpc.GRPC_AttendantPayload{
// 				Handler: "test",
// 			},
// 			expected: nil,
// 		},
// 		{
// 			name: "WithPayload",
// 			payload: &kafka_grpc.GRPC_AttendantPayload{
// 				Handler: "test",
// 				Data: &kafka_grpc.GRPC_AttendantPayload_Keys{
// 					Keys: &kafka_grpc.ECCKeys{
// 						EccKeys: []*kafka_grpc.ECCKey{
// 							{
// 								Ecu:           "ecu",
// 								Env:           "env",
// 								PubKeyLevel_1: &pub1,
// 								PubKeyLevel_2: &pub2,
// 								Level_1:       &priv1,
// 								Level_2:       &priv2,
// 							},
// 						},
// 					},
// 				},
// 			},
// 			expected: []ECCKeys{
// 				{
// 					ECU:      "ecu",
// 					Env:      "env",
// 					PubKey1:  &pub11,
// 					PubKey2:  &pub22,
// 					PrivKey1: &priv11,
// 					PrivKey2: &priv22,
// 				},
// 			},
// 		},
// 	}

// 	for _, tc := range testCases {
// 		t.Run(tc.name, func(t *testing.T) {
// 			result := GRPCToECCKeys(tc.payload)

// 			// Compare the result with expected value
// 			if !equal(result, tc.expected) {
// 				t.Errorf("Test case %s failed. Expected: %v, got: %v", tc.name, tc.expected, result)
// 			}
// 		})
// 	}
// }

// Helper function to check equality of slices of ECCKeys
// func equal(a, b []ECCKeys) bool {
// 	if len(a) != len(b) {
// 		return false
// 	}
// 	for i := range a {
// 		if a[i] != b[i] {
// 			return false
// 		}
// 	}
// 	return true
// }

func TestRemoteCMD(t *testing.T) {

	input := []struct {
		name string
		cmd  *RemoteCommandRequest
	}{
		{
			name: "With valid data",
			cmd: &RemoteCommandRequest{
				VIN: "1F15K3R45N1234567",
				RemoteCommandSource: RemoteCommandSource{
					Command: "temp_cabin",
					Data:    elptr.ElPtr("20"),
					Start:   elptr.ElPtr(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
					End:     elptr.ElPtr(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
				},
			},
		},
		{
			name: "With end date null",
			cmd: &RemoteCommandRequest{
				VIN: "1F15K3R45N1234567",
				RemoteCommandSource: RemoteCommandSource{
					Command: "temp_cabin",
					Data:    elptr.ElPtr("20"),
					Start:   elptr.ElPtr(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)),
					End:     nil,
				},
			},
		},
		{
			name: "With all values with zero",
			cmd:  &RemoteCommandRequest{},
		},
		{
			name: "With null data",
			cmd:  nil,
		},
		{
			name: "With zero cmd values",
			cmd: &RemoteCommandRequest{
				RemoteCommandSource: RemoteCommandSource{},
			},
		},
	}

	for _, in := range input {
		t.Run(in.name, func(t *testing.T) {
			b := toBinaryArray(in.cmd)

			rawMsg := MessageRawJSON{
				Handler: "remote_command",
				Data:    b,
			}
			protoCmd := RemoteCMDToGRPC(rawMsg)

			resCMD := GRPCToRemotCMD(protoCmd)
			protoCmdInBinary := toBinaryArray(resCMD)

			if string(b) != string(protoCmdInBinary) {
				t.Errorf("Expected %v, got %v", string(b), string(protoCmdInBinary))
			}
		})
	}

}
