package gateway

import (
	"strings"
	"testing"

	"lingniu-vehicle-ingest/go/vehicle-gateway/internal/envelope"
)

func TestCanonicalRawEnvelopeDropsBareStandardizedFields(t *testing.T) {
	original := envelope.FrameEnvelope{
		Protocol:  envelope.ProtocolJT808,
		EventKind: envelope.EventKindFields,
		Parsed: map[string]any{
			"location": map[string]any{"latitude": 30.5, "speed_kmh": 20},
		},
		Fields: map[string]any{
			envelope.FieldLatitude: 30.5,
			envelope.FieldSpeedKMH: 20,
		},
		ParsedFields: map[string]any{
			"jt808.location.latitude":  30.5,
			"jt808.location.speed_kmh": 20,
		},
	}

	canonical := canonicalRawEnvelope(original)
	if canonical.EventKind != envelope.EventKindRaw {
		t.Fatalf("event kind = %q", canonical.EventKind)
	}
	if len(canonical.Fields) != 0 {
		t.Fatalf("canonical raw leaked bare fields: %#v", canonical.Fields)
	}
	if len(canonical.Parsed) != 0 {
		t.Fatalf("canonical raw leaked duplicate parsed tree: %#v", canonical.Parsed)
	}
	if len(canonical.ParsedFields) != 2 {
		t.Fatalf("canonical raw lost protocol fields: %#v", canonical.ParsedFields)
	}
	if len(original.Fields) != 2 {
		t.Fatalf("canonical copy mutated in-process parser fields: %#v", original.Fields)
	}
	if len(original.Parsed) != 1 {
		t.Fatalf("canonical copy mutated in-process parsed tree: %#v", original.Parsed)
	}
}

func TestCanonicalRawEnvelopeReducesDuplicateParsedPayload(t *testing.T) {
	original := envelope.FrameEnvelope{
		Protocol:    envelope.ProtocolGB32960,
		MessageID:   "0x02",
		VIN:         "LTESTVIN000000001",
		ParseStatus: envelope.ParseOK,
		Parsed: map[string]any{
			"data_units": []any{map[string]any{
				"name":  "vendor",
				"value": strings.Repeat("x", 4096),
			}},
		},
		ParsedFields: map[string]any{
			"gb32960.vendor.value": strings.Repeat("x", 4096),
		},
	}
	before, err := original.MarshalJSONBytes()
	if err != nil {
		t.Fatal(err)
	}
	after, err := canonicalRawEnvelope(original).MarshalJSONBytes()
	if err != nil {
		t.Fatal(err)
	}
	if len(after)*100 >= len(before)*65 {
		t.Fatalf("canonical raw should remove the duplicate parsed tree: before=%d after=%d", len(before), len(after))
	}
	t.Logf("canonical raw bytes before=%d after=%d reduction=%.1f%%", len(before), len(after), 100*(1-float64(len(after))/float64(len(before))))
}
