package service

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	apiv1 "github.com/tidbcloud/cluster-service-ng/api/tidbcloud/cluster-agent/v1"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sigs.k8s.io/controller-runtime/pkg/client/fake"
)

func TestAgentService_GetNode(t *testing.T) {
	tests := []struct {
		name        string
		nodes       []*corev1.Node
		req         *apiv1.GetNodeReq
		wantName    string
		wantErr     bool
		errContains string
	}{
		{
			name: "get existing node",
			nodes: []*corev1.Node{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name: "node-1",
						Labels: map[string]string{
							"tidb.cluster.id": "test-cluster-123",
						},
					},
					Spec: corev1.NodeSpec{
						ProviderID: "aws:///us-west-2/i-1234567890abcdef0",
					},
					Status: corev1.NodeStatus{
						Conditions: []corev1.NodeCondition{
							{
								Type:   corev1.NodeReady,
								Status: corev1.ConditionTrue,
							},
						},
					},
				},
			},
			req: &apiv1.GetNodeReq{
				ClusterId: "test-cluster-123",
				NodeName:  "node-1",
			},
			wantName: "node-1",
			wantErr:  false,
		},
		{
			name: "node not found",
			nodes: []*corev1.Node{
				{
					ObjectMeta: metav1.ObjectMeta{
						Name: "node-1",
						Labels: map[string]string{
							"tidb.cluster.id": "test-cluster-123",
						},
					},
				},
			},
			req: &apiv1.GetNodeReq{
				ClusterId: "test-cluster-123",
				NodeName:  "nonexistent-node",
			},
			wantErr:     true,
			errContains: "not found",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			builder := fake.NewClientBuilder()
			for _, node := range tt.nodes {
				builder = builder.WithObjects(node)
			}
			cli := builder.Build()
			service := NewAgentService(cli, nil)

			ctx := context.Background()
			resp, err := service.GetNode(ctx, tt.req)

			if tt.wantErr {
				require.Error(t, err)
				if tt.errContains != "" {
					assert.Contains(t, err.Error(), tt.errContains)
				}
				return
			}

			require.NoError(t, err)
			require.NotNil(t, resp)
			assert.Equal(t, tt.wantName, resp.K8SMetadata.Name)
		})
	}
}
