package tioperator

import (
	"testing"
	"time"

	v1alpha1br "github.com/pingcap/tidb-operator/api/v2/br/v1alpha1"
	"github.com/pingcap/tidb-operator/api/v2/core/v1alpha1"
	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestIsTiBRSyncedReady(t *testing.T) {
	tests := []struct {
		name     string
		tibr     *v1alpha1br.TiBR
		expected bool
	}{
		{
			name:     "nil tibr",
			tibr:     nil,
			expected: false,
		},
		{
			name: "both Ready and Synced true",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: []v1.Condition{
							{Type: "Ready", Status: v1.ConditionTrue},
							{Type: "Synced", Status: v1.ConditionTrue},
						},
					},
				},
			},
			expected: true,
		},
		{
			name: "only Ready true",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: []v1.Condition{
							{Type: "Ready", Status: v1.ConditionTrue},
							{Type: "Synced", Status: v1.ConditionFalse},
						},
					},
				},
			},
			expected: false,
		},
		{
			name: "only Synced true",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: []v1.Condition{
							{Type: "Ready", Status: v1.ConditionFalse},
							{Type: "Synced", Status: v1.ConditionTrue},
						},
					},
				},
			},
			expected: false,
		},
		{
			name: "neither true",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: []v1.Condition{
							{Type: "Ready", Status: v1.ConditionFalse},
							{Type: "Synced", Status: v1.ConditionFalse},
						},
					},
				},
			},
			expected: false,
		},
		{
			name: "only one condition",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: []v1.Condition{
							{Type: "Synced", Status: v1.ConditionTrue},
						},
					},
				},
			},
			expected: false,
		},
		{
			name: "no conditions",
			tibr: &v1alpha1br.TiBR{
				Status: v1alpha1br.TiBRStatus{
					CommonStatus: v1alpha1.CommonStatus{
						Conditions: nil,
					},
				},
			},
			expected: false,
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got := IsTiBRSyncedReady(tc.tibr)
			if got != tc.expected {
				t.Errorf("expected %v, got %v", tc.expected, got)
			}
		})
	}
}

func TestTiBRConditionLogValues(t *testing.T) {
	transitionTime := v1.NewTime(time.Date(2026, time.July, 9, 2, 42, 1, 123, time.UTC))
	condition := &v1.Condition{
		Status:             v1.ConditionFalse,
		Reason:             "NotReady",
		Message:            "ready replica of statefulset is not 1",
		LastTransitionTime: transitionTime,
	}

	if got := conditionStatus(condition); got != string(v1.ConditionFalse) {
		t.Fatalf("conditionStatus() = %q, want %q", got, v1.ConditionFalse)
	}
	if got := conditionReason(condition); got != condition.Reason {
		t.Fatalf("conditionReason() = %q, want %q", got, condition.Reason)
	}
	if got := conditionMessage(condition); got != condition.Message {
		t.Fatalf("conditionMessage() = %q, want %q", got, condition.Message)
	}
	if got := conditionLastTransitionTime(condition); got != transitionTime.UTC().Format(time.RFC3339Nano) {
		t.Fatalf("conditionLastTransitionTime() = %q, want %q", got, transitionTime.UTC().Format(time.RFC3339Nano))
	}

	if got := conditionStatus(nil); got != "Missing" {
		t.Fatalf("conditionStatus(nil) = %q, want Missing", got)
	}
	if got := conditionReason(nil); got != "" {
		t.Fatalf("conditionReason(nil) = %q, want empty", got)
	}
	if got := conditionMessage(nil); got != "" {
		t.Fatalf("conditionMessage(nil) = %q, want empty", got)
	}
	if got := conditionLastTransitionTime(nil); got != "" {
		t.Fatalf("conditionLastTransitionTime(nil) = %q, want empty", got)
	}
}

func TestTiBRCRNameOfRestore(t *testing.T) {
	tests := []struct {
		name      string
		restoreId string
		expected  string
	}{
		{
			name:      "simple restore id",
			restoreId: "abc123",
			expected:  "restore-abc123",
		},
		{
			name:      "empty restore id",
			restoreId: "",
			expected:  "restore-",
		},
		{
			name:      "restore id with special characters",
			restoreId: "test-restore-001",
			expected:  "restore-test-restore-001",
		},
		{
			name:      "long restore id",
			restoreId: "very-long-restore-id-with-many-characters-1234567890",
			expected:  "restore-very-long-restore-id-with-many-characters-1234567890",
		},
	}

	for _, tc := range tests {
		t.Run(tc.name, func(t *testing.T) {
			got := TiBRCRNameOfRestore(tc.restoreId)
			if got != tc.expected {
				t.Errorf("expected %q, got %q", tc.expected, got)
			}
		})
	}
}

func TestDefaultTiBRNames(t *testing.T) {
	if DefaultTiBRName != "tibr-default" {
		t.Errorf("expected DefaultTiBRName to be 'tibr-default', got %q", DefaultTiBRName)
	}
	if DefaultTiBRGCRName != "tibrgc-default" {
		t.Errorf("expected DefaultTiBRGCRName to be 'tibrgc-default', got %q", DefaultTiBRGCRName)
	}
}
