package handlers

import (
	"testing"

	"github.com/containerd/containerd/v2/core/snapshots"
)

func TestSnapshotLineage(t *testing.T) {
	t.Parallel()

	tests := []struct {
		name      string
		root      string
		input     []snapshots.Info
		wantFound bool
		wantNames []string
	}{
		{
			name: "walk full snapshot ancestry",
			root: "active-3",
			input: []snapshots.Info{
				{Name: "active-3", Parent: "version-2"},
				{Name: "version-2", Parent: "version-1"},
				{Name: "version-1", Parent: "sha256:base-layer"},
				{Name: "sha256:base-layer", Parent: ""},
				{Name: "unrelated", Parent: ""},
			},
			wantFound: true,
			wantNames: []string{"active-3", "version-2", "version-1", "sha256:base-layer"},
		},
		{
			name: "root snapshot not found",
			root: "missing",
			input: []snapshots.Info{
				{Name: "active-1", Parent: "sha256:base-layer"},
				{Name: "sha256:base-layer", Parent: ""},
			},
			wantFound: false,
			wantNames: nil,
		},
		{
			name: "missing parent keeps known chain",
			root: "active-1",
			input: []snapshots.Info{
				{Name: "active-1", Parent: "version-1"},
			},
			wantFound: true,
			wantNames: []string{"active-1"},
		},
		{
			name: "cycle is bounded by visited set",
			root: "a",
			input: []snapshots.Info{
				{Name: "a", Parent: "b"},
				{Name: "b", Parent: "a"},
			},
			wantFound: true,
			wantNames: []string{"a", "b"},
		},
	}

	for _, tt := range tests {
		tt := tt
		t.Run(tt.name, func(t *testing.T) {
			t.Parallel()

			got, found := snapshotLineage(tt.root, tt.input)
			if found != tt.wantFound {
				t.Fatalf("found = %v, want %v", found, tt.wantFound)
			}
			if !found {
				return
			}
			if len(got) != len(tt.wantNames) {
				t.Fatalf("len(got) = %d, want %d", len(got), len(tt.wantNames))
			}
			for i := range tt.wantNames {
				if got[i].Name != tt.wantNames[i] {
					t.Fatalf("got[%d].Name = %q, want %q", i, got[i].Name, tt.wantNames[i])
				}
			}
		})
	}
}
