package analyzer

import (
	"reflect"
	"testing"
)

func TestPropMap_Get(t *testing.T) {
	m := PropMap{
		"a": "value-a",
		"nested": PropMap{
			"b": "value-b",
			"deep": PropMap{
				"c": "value-c",
			},
		},
	}

	tests := []struct {
		name string
		key  string
		want interface{}
	}{
		{"simple key", "a", "value-a"},
		{"nested key", "nested.b", "value-b"},
		{"deeply nested", "nested.deep.c", "value-c"},
		{"non-existent top", "x", nil},
		{"non-existent nested", "nested.x", nil},
		{"empty key", "", nil},
		{"partial path", "nested", PropMap{"b": "value-b", "deep": PropMap{"c": "value-c"}}},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := m.Get(tt.key)
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("PropMap.Get(%q) = %v, want %v", tt.key, got, tt.want)
			}
		})
	}
}

func TestPropMap_Get_NilMap(t *testing.T) {
	var m PropMap
	if got := m.Get("any"); got != nil {
		t.Errorf("nil PropMap.Get() = %v, want nil", got)
	}
}

func TestPropMap_Get_EmptyMap(t *testing.T) {
	m := PropMap{}
	if got := m.Get("any"); got != nil {
		t.Errorf("empty PropMap.Get() = %v, want nil", got)
	}
}

func TestPropMap_Get_IntermediateNonMap(t *testing.T) {
	m := PropMap{
		"a": "hello",
	}
	if got := m.Get("a.b.c"); got != nil {
		t.Errorf("PropMap.Get() through non-map = %v, want nil", got)
	}
}

func TestCombinedPropMap_Get(t *testing.T) {
	cm := CombinedPropMap{
		"tls": PropMap{
			"req": PropMap{
				"sni": "example.com",
			},
		},
		"http": PropMap{
			"resp": PropMap{
				"status": 200,
			},
		},
	}

	tests := []struct {
		name     string
		analyzer string
		key      string
		want     interface{}
	}{
		{"tls sni", "tls", "req.sni", "example.com"},
		{"http status", "http", "resp.status", 200},
		{"unknown analyzer", "dns", "any", nil},
		{"valid analyzer bad key", "tls", "req.nonexistent", nil},
		{"empty analyzer", "", "key", nil},
		{"empty key", "tls", "", nil},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			got := cm.Get(tt.analyzer, tt.key)
			if !reflect.DeepEqual(got, tt.want) {
				t.Errorf("CombinedPropMap.Get(%q, %q) = %v, want %v", tt.analyzer, tt.key, got, tt.want)
			}
		})
	}
}

func TestCombinedPropMap_Get_Nil(t *testing.T) {
	var cm CombinedPropMap
	if got := cm.Get("any", "key"); got != nil {
		t.Errorf("nil CombinedPropMap.Get() = %v, want nil", got)
	}
}

func TestPropUpdateType_Values(t *testing.T) {
	if PropUpdateNone != 0 {
		t.Errorf("PropUpdateNone = %d, want 0", PropUpdateNone)
	}
	if PropUpdateMerge != 1 {
		t.Errorf("PropUpdateMerge = %d, want 1", PropUpdateMerge)
	}
	if PropUpdateReplace != 2 {
		t.Errorf("PropUpdateReplace = %d, want 2", PropUpdateReplace)
	}
	if PropUpdateDelete != 3 {
		t.Errorf("PropUpdateDelete = %d, want 3", PropUpdateDelete)
	}
}
