package handler

import (
	"errors"
	"testing"

	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestK8sPods2ClientPodsSkipsInvalidStores(t *testing.T) {
	pods := []*corev1.Pod{
		{
			ObjectMeta: metav1.ObjectMeta{
				Name: "tiflash-main-0",
				Labels: map[string]string{
					"apps.kubernetes.io/pod-index": "0",
				},
			},
			Status: corev1.PodStatus{PodIP: "10.0.0.1"},
		},
		{
			ObjectMeta: metav1.ObjectMeta{
				Name: "tiflash-main-1",
			},
			Status: corev1.PodStatus{PodIP: "10.0.0.2"},
		},
	}

	clientPods := k8sPods2ClientPods(pods, "tiflash-{POOL}-{INDEX}.svc", "main")
	if len(clientPods) != 1 {
		t.Fatalf("expected one valid store, got %d", len(clientPods))
	}
	if got := clientPods[0].Address; got != "tiflash-main-0.svc" {
		t.Fatalf("unexpected address: %q", got)
	}
}

func TestFirstValidPoolFallsBackToDefault(t *testing.T) {
	poolName, value, err := firstValidPool("analytics", "main", func(poolName string) (string, bool, error) {
		switch poolName {
		case "analytics":
			return "", false, nil
		case "main":
			return "ok", true, nil
		default:
			return "", false, nil
		}
	})
	if err != nil {
		t.Fatalf("firstValidPool returned error: %v", err)
	}
	if poolName != "main" {
		t.Fatalf("expected fallback pool to be main, got %q", poolName)
	}
	if value != "ok" {
		t.Fatalf("unexpected returned value: %q", value)
	}
}

func TestFirstValidPoolReturnsLastErrorWhenNoPoolIsUsable(t *testing.T) {
	_, _, err := firstValidPool("analytics", "main", func(poolName string) (string, bool, error) {
		return "", false, errors.New(poolName + " failed")
	})
	if err == nil {
		t.Fatalf("expected error")
	}
	if got := err.Error(); got == "" || got == "no valid store found in preferred pool or default pool" {
		t.Fatalf("expected wrapped error, got %q", got)
	}
}
