package idempotency_test

import (
	"testing"

	"github.com/break/junhong_cmp_fiber/pkg/idempotency"
)

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

	left, err := idempotency.Fingerprint(map[string]any{
		"amount": 100,
		"remark": "  月度充值  ",
		"token":  "token-a",
		"nested": map[string]any{"enabled": true, "count": 2},
	})
	if err != nil {
		t.Fatalf("计算第一个请求指纹失败：%v", err)
	}
	right, err := idempotency.Fingerprint(map[string]any{
		"nested":    map[string]any{"count": 2, "enabled": true},
		"timestamp": 1720000000,
		"remark":    "月度充值",
		"amount":    100,
	})
	if err != nil {
		t.Fatalf("计算第二个请求指纹失败：%v", err)
	}

	if left.Algorithm != idempotency.FingerprintAlgorithmV1 {
		t.Fatalf("算法版本不正确：%s", left.Algorithm)
	}
	if left.Value != right.Value {
		t.Fatalf("仅传输字段或对象顺序变化不应改变指纹：%s != %s", left.Value, right.Value)
	}
}

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

	original := idempotency.Record{
		Scope:       idempotency.Scope{Subject: "account:7", Operation: "agent-recharge.create"},
		RequestID:   "request-1",
		Fingerprint: idempotency.FingerprintValue{Algorithm: idempotency.FingerprintAlgorithmV1, Value: "abc"},
	}

	if got := idempotency.Classify(original, original.Scope, "request-1", original.Fingerprint); got != idempotency.ReplaySame {
		t.Fatalf("相同命令应识别为重放，得到：%s", got)
	}
	if got := idempotency.Classify(original, original.Scope, "request-1", idempotency.FingerprintValue{Algorithm: idempotency.FingerprintAlgorithmV1, Value: "def"}); got != idempotency.ReplayConflict {
		t.Fatalf("同作用域同请求 ID 的不同内容应冲突，得到：%s", got)
	}
	otherScope := idempotency.Scope{Subject: "account:8", Operation: original.Scope.Operation}
	if got := idempotency.Classify(original, otherScope, "request-1", original.Fingerprint); got != idempotency.ReplayUnrelated {
		t.Fatalf("不同主体不应相互污染，得到：%s", got)
	}
}
