package http

import (
	"net/http/httptest"
	"strings"
	"testing"

	"hyapp/services/gateway-service/internal/transport/http/httpkit"
)

// 设备资料头是 App 全局注入的，两个 meta builder（httpkit 通用版与 auth 专用版）都必须透传，
// 否则登录链路与业务链路的设备档案会出现来源分叉。
func TestRequestMetaBuildersCarryDeviceProfileHeaders(t *testing.T) {
	request := httptest.NewRequest("POST", "/api/v1/auth/login", nil)
	request.Header.Set("X-Device-Model", "Redmi Note 8 Pro")
	request.Header.Set("X-Device-Manufacturer", "Xiaomi")
	request.Header.Set("X-OS-Version", "13")
	request.Header.Set("X-Device-IMEI", "123456789012345")

	authMeta := authRequestMetaWithLoginContext(request, "dev-1", "android", "en", "Asia/Riyadh", "", "")
	if authMeta.GetDeviceModel() != "Redmi Note 8 Pro" || authMeta.GetDeviceManufacturer() != "Xiaomi" ||
		authMeta.GetOsVersion() != "13" || authMeta.GetImei() != "123456789012345" {
		t.Fatalf("auth meta must carry device profile headers: %+v", authMeta)
	}

	userMeta := httpkit.UserMeta(request, "dev-1")
	if userMeta.GetDeviceModel() != "Redmi Note 8 Pro" || userMeta.GetDeviceManufacturer() != "Xiaomi" ||
		userMeta.GetOsVersion() != "13" || userMeta.GetImei() != "123456789012345" {
		t.Fatalf("httpkit user meta must carry device profile headers: %+v", userMeta)
	}

	// 头缺失时保持空串：user-service 端“非空覆盖”依赖空值不参与合并。
	bare := httptest.NewRequest("POST", "/api/v1/auth/refresh", nil)
	bareMeta := authRequestMetaWithLoginContext(bare, "dev-1", "", "", "", "", "")
	if bareMeta.GetDeviceModel() != "" || bareMeta.GetImei() != "" {
		t.Fatalf("missing headers must map to empty meta fields: %+v", bareMeta)
	}
}

// body device/os_version 属于旧协议；标准客户端只发设备头，回退逻辑保证 register 快照不再为空，
// 同时 body 显式值仍优先，旧客户端行为不变。
func TestDeviceFieldsWithHeaderFallback(t *testing.T) {
	request := httptest.NewRequest("POST", "/api/v1/auth/register", nil)
	request.Header.Set("X-Device-Model", "iPhone17,2")
	request.Header.Set("X-OS-Version", "18.1")
	meta := authRequestMetaWithLoginContext(request, "dev-2", "ios", "", "", "", "")

	device, osVersion := deviceFieldsWithHeaderFallback("", " ", meta)
	if device != "iPhone17,2" || osVersion != "18.1" {
		t.Fatalf("empty body fields must fall back to headers: device=%q os=%q", device, osVersion)
	}

	device, osVersion = deviceFieldsWithHeaderFallback("Pixel 8", "14", meta)
	if device != "Pixel 8" || osVersion != "14" {
		t.Fatalf("body fields must win over headers: device=%q os=%q", device, osVersion)
	}
}

// H5 与原生共用设备上报协议，新设备头必须落进默认 CORS 允许集，否则浏览器 preflight 直接拦掉。
func TestCORSDefaultHeadersAllowDeviceProfile(t *testing.T) {
	config := normalizeCORSConfig(CORSConfig{})
	allowedHeaders := "," + strings.ToLower(strings.Join(config.AllowedHeaders, ",")) + ","
	for _, header := range []string{"X-Device-Model", "X-Device-Manufacturer", "X-OS-Version", "X-Device-IMEI"} {
		if !strings.Contains(allowedHeaders, ","+strings.ToLower(header)+",") {
			t.Fatalf("default CORS headers must allow device profile header %q: %+v", header, config.AllowedHeaders)
		}
	}
}
