package serviceactor

import (
	"testing"

	"github.com/stretchr/testify/require"
)

func TestEventDeliveryReplayMatchesEvent(t *testing.T) {
	t.Parallel()

	existing := EventDelivery{
		WorkspaceID:          "wsp_1",
		EventSubscriptionID:  "sub_1",
		WebhookReceiptID:     "receipt_1",
		EventType:            "agentteam.app.notification.action",
		EventAction:          "approve",
		EventID:              "action_1",
		EventKey:             "notification_1:approve:action_1",
		EventPayload:         []byte(`{"action":{"input":{"b":2,"a":1}}}`),
		ExternalResourceType: "app_notification",
		ExternalResourceKey:  "notification_1",
		ExternalResourceRef:  "notification_1",
	}
	replay := EventDeliveryReserve{
		WorkspaceID:          " wsp_1 ",
		EventSubscriptionID:  " sub_1 ",
		WebhookReceiptID:     " receipt_1 ",
		EventType:            " agentteam.app.notification.action ",
		EventAction:          " approve ",
		EventID:              " action_1 ",
		EventKey:             " notification_1:approve:action_1 ",
		EventPayload:         []byte(`{"action":{"input":{"a":1,"b":2}}}`),
		ExternalResourceType: " app_notification ",
		ExternalResourceKey:  " notification_1 ",
		ExternalResourceRef:  " notification_1 ",
	}
	require.True(t, eventDeliveryReplayMatches(existing, replay))

	changed := replay
	changed.EventPayload = []byte(`{"action":{"input":{"a":1,"b":3}}}`)
	require.False(t, eventDeliveryReplayMatches(existing, changed))

	changed = replay
	changed.EventAction = "reject"
	require.False(t, eventDeliveryReplayMatches(existing, changed))

	// A receipt identifies one transport attempt, not the logical event. A
	// failed delivery may be retried from a replacement receipt.
	changed = replay
	changed.WebhookReceiptID = "receipt_2"
	require.True(t, eventDeliveryReplayMatches(existing, changed))

	// Optional resource snapshots omitted by a legacy caller do not turn an
	// otherwise identical event into a false conflict.
	legacy := replay
	legacy.WebhookReceiptID = ""
	legacy.ExternalResourceType = ""
	legacy.ExternalResourceKey = ""
	legacy.ExternalResourceRef = ""
	require.True(t, eventDeliveryReplayMatches(existing, legacy))
}

func TestEventDeliveryJSONEqualNormalizesEmptyObjects(t *testing.T) {
	t.Parallel()

	require.True(t, eventDeliveryJSONEqual(nil, []byte(`{}`)))
	require.True(t, eventDeliveryJSONEqual([]byte(`null`), []byte(`{}`)))
	require.True(t, eventDeliveryJSONEqual([]byte(`{"b":2,"a":1}`), []byte(`{"a":1,"b":2}`)))
	require.False(t, eventDeliveryJSONEqual([]byte(`{"a":1}`), []byte(`{"a":2}`)))
	require.False(t, eventDeliveryJSONEqual([]byte(`{"a":9007199254740992}`), []byte(`{"a":9007199254740993}`)))
	require.False(t, eventDeliveryJSONEqual([]byte(`not-json`), []byte(`not-json`)))
	require.False(t, eventDeliveryJSONEqual([]byte(`{}`), []byte(`{} {}`)))
}
