package cmdpacks

import (
	"testing"

	"github.com/stretchr/testify/assert"
	"lmika.dev/cmd/dynamo-browse/internal/dynamo-browse/models"
)

func TestAttrPathProxy_Index(t *testing.T) {
	tests := []struct {
		descr    string
		attrPath models.AttrPathNode
		index    int
		want     string
		wantNil  bool
	}{
		{
			descr:    "return leaf 1",
			attrPath: models.AttrPathNode{Key: "leaf"},
			index:    -1,
			want:     "leaf",
		},
		{
			descr:    "return leaf 2",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent"}},
			index:    -1,
			want:     "leaf",
		},
		{
			descr:    "return parent 1",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent"}},
			index:    -2,
			want:     "parent",
		},
		{
			descr:    "return parent 1",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent", Parent: &models.AttrPathNode{Key: "grandparent"}}},
			index:    -2,
			want:     "parent",
		},
		{
			descr:    "return parent 3",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent", Parent: &models.AttrPathNode{Key: "grandparent"}}},
			index:    -3,
			want:     "grandparent",
		},
		{
			descr:    "return root 1",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent", Parent: &models.AttrPathNode{Key: "grandparent"}}},
			index:    0,
			want:     "grandparent",
		},
		{
			descr:    "return root 2",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent"}},
			index:    0,
			want:     "parent",
		},
		{
			descr:    "return root 3",
			attrPath: models.AttrPathNode{Key: "leaf"},
			index:    0,
			want:     "leaf",
		},
		{
			descr:    "return first child 1",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent", Parent: &models.AttrPathNode{Key: "grandparent"}}},
			index:    1,
			want:     "parent",
		},
		{
			descr:    "return first child 2",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent"}},
			index:    1,
			want:     "leaf",
		},
		{
			descr:    "return nil 1",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent", Parent: &models.AttrPathNode{Key: "grandparent"}}},
			index:    -5,
			wantNil:  true,
		},
		{
			descr:    "return nil 2",
			attrPath: models.AttrPathNode{Key: "leaf", Parent: &models.AttrPathNode{Key: "parent"}},
			index:    56,
			wantNil:  true,
		},
	}
	for _, tt := range tests {
		t.Run(tt.descr, func(t *testing.T) {
			proxy := attrPathProxy{&tt.attrPath}
			if tt.wantNil {
				assert.Nil(t, proxy.Index(tt.index))
			} else {
				assert.Equal(t, tt.want, proxy.Index(tt.index).String())
			}
		})
	}
}
