package outboundintentv1

import (
	"encoding/json"
	"testing"
)

func TestDecodeMailDeliveryV2PreservesRecipientClassesAndHTML(t *testing.T) {
	payload := MailDeliveryV2{
		Version: MailPayloadFormatV2, AuthorizedActorID: "user-1",
		ToAddresses: []string{"to@example.com"}, CcAddresses: []string{"cc@example.com"},
		BccAddresses: []string{"bcc@example.com"}, Subject: "Hello", TextBody: "Plain",
		HTMLBody: "<p><strong>Hello</strong></p>",
	}
	intent := canonicalMailV2Intent(t, payload)
	got, err := DecodeMailDeliveryV2(intent)
	if err != nil {
		t.Fatalf("DecodeMailDeliveryV2: %v", err)
	}
	if len(got.CcAddresses) != 1 || got.CcAddresses[0] != "cc@example.com" ||
		len(got.BccAddresses) != 1 || got.BccAddresses[0] != "bcc@example.com" || got.HTMLBody != payload.HTMLBody {
		t.Fatalf("decoded payload = %#v", got)
	}
}

func TestDecodeMailDeliveryV2RejectsRecipientAmbiguityAndUnsafeShape(t *testing.T) {
	base := MailDeliveryV2{
		Version: MailPayloadFormatV2, AuthorizedActorID: "user-1",
		ToAddresses: []string{"to@example.com"}, Subject: "Hello", TextBody: "Plain",
	}
	tests := []struct {
		name   string
		mutate func(*MailDeliveryV2)
	}{
		{"duplicate across classes", func(value *MailDeliveryV2) { value.CcAddresses = []string{"TO@example.com"} }},
		{"header injection", func(value *MailDeliveryV2) { value.BccAddresses = []string{"bcc@example.com\r\nX: y"} }},
		{"empty to", func(value *MailDeliveryV2) { value.ToAddresses = nil }},
		{"empty text alternative", func(value *MailDeliveryV2) { value.TextBody = "" }},
		{"html control", func(value *MailDeliveryV2) { value.HTMLBody = "<p>x</p>\x00" }},
	}
	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			value := base
			test.mutate(&value)
			if _, err := DecodeMailDeliveryV2(canonicalMailV2Intent(t, value)); err == nil {
				t.Fatal("DecodeMailDeliveryV2 accepted invalid payload")
			}
		})
	}
}

func canonicalMailV2Intent(t *testing.T, payload MailDeliveryV2) Intent {
	t.Helper()
	raw, err := json.Marshal(payload)
	if err != nil {
		t.Fatal(err)
	}
	intent := testIntent(raw, 41)
	intent.Operation = OperationSendMail
	intent.PayloadFormatVersion = MailPayloadFormatV2
	return intent
}
