package logger

import (
	"testing"

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

func TestClientDebugEnabled(t *testing.T) {
	t.Run("non production enables debug by default", func(t *testing.T) {
		assert.True(t, ClientDebugEnabled("dev", ""))
		assert.True(t, ClientDebugEnabled("local", ""))
	})

	t.Run("explicit debug flag applies in non production", func(t *testing.T) {
		assert.True(t, ClientDebugEnabled("dev", "true"))
		assert.True(t, ClientDebugEnabled("local", "1"))
		assert.False(t, ClientDebugEnabled("dev", "false"))
		assert.False(t, ClientDebugEnabled("local", "0"))
	})

	t.Run("production disables debug by default", func(t *testing.T) {
		assert.False(t, ClientDebugEnabled("production", ""))
		assert.False(t, ClientDebugEnabled("prod", "false"))
		assert.False(t, ClientDebugEnabled("stage", ""))
		assert.False(t, ClientDebugEnabled("staging", "false"))
	})

	t.Run("production accepts explicit debug override", func(t *testing.T) {
		assert.True(t, ClientDebugEnabled("production", "true"))
		assert.True(t, ClientDebugEnabled("production", "1"))
		assert.True(t, ClientDebugEnabled("prod", "on"))
	})
}

func TestShouldAcceptClientLog(t *testing.T) {
	assert.False(t, ShouldAcceptClientLog("production", "", "INFO"))
	assert.False(t, ShouldAcceptClientLog("production", "", "DEBUG"))
	assert.False(t, ShouldAcceptClientLog("stage", "", "INFO"))
	assert.False(t, ShouldAcceptClientLog("stage", "", "DEBUG"))
	assert.True(t, ShouldAcceptClientLog("production", "", "WARN"))
	assert.True(t, ShouldAcceptClientLog("production", "", "ERROR"))
	assert.True(t, ShouldAcceptClientLog("stage", "", "WARN"))
	assert.True(t, ShouldAcceptClientLog("stage", "", "ERROR"))
	assert.True(t, ShouldAcceptClientLog("production", "true", "INFO"))
	assert.True(t, ShouldAcceptClientLog("dev", "", "INFO"))
	assert.False(t, ShouldAcceptClientLog("dev", "false", "INFO"))
	assert.True(t, ShouldAcceptClientLog("dev", "false", "WARN"))
}

func TestShouldFilterNoisyClientInfo(t *testing.T) {
	assert.True(t, ShouldFilterNoisyClientInfo("production", "", "Navigating to /ko/signin"))
	assert.True(t, ShouldFilterNoisyClientInfo("stage", "", "Navigating to /ko/signin"))
	assert.False(t, ShouldFilterNoisyClientInfo("production", "true", "Navigating to /ko/signin"))
	assert.False(t, ShouldFilterNoisyClientInfo("dev", "", "Navigating to /ko/signin"))
	assert.True(t, ShouldFilterNoisyClientInfo("dev", "false", "Navigating to /ko/signin"))
}

func TestSanitizeClientLogData(t *testing.T) {
	input := map[string]any{
		"token": "raw-token",
		"safe":  "ok",
		"nested": map[string]any{
			"new_password": "secret-1",
			"path":         "/ko/profile",
		},
		"arr": []any{
			map[string]any{"authorization": "Bearer abc"},
			"token=abc123",
		},
	}

	result := SanitizeClientLogData(input)

	assert.Equal(t, "*****", result["token"])
	assert.Equal(t, "ok", result["safe"])

	nested := result["nested"].(map[string]any)
	assert.Equal(t, "*****", nested["new_password"])
	assert.Equal(t, "/ko/profile", nested["path"])

	arr := result["arr"].([]any)
	first := arr[0].(map[string]any)
	assert.Equal(t, "*****", first["authorization"])
	assert.Equal(t, "token=*****", arr[1])
}

func TestSanitizeClientLogMessage(t *testing.T) {
	msg := `FLUTTER_ERROR token=abc123 payload={"password":"hello","safe":"ok"} authorization:BearerX`
	sanitized := SanitizeClientLogMessage(msg)
	assert.NotContains(t, sanitized, "abc123")
	assert.NotContains(t, sanitized, `"password":"hello"`)
	assert.Contains(t, sanitized, `"password":"*****"`)
	assert.Contains(t, sanitized, "token=*****")
	assert.Contains(t, sanitized, "authorization=*****")
}
