package cvt

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func TestUpgradeOperation2PB_currentStep(t *testing.T) {
	now := metav1.NewTime(time.Date(2026, 6, 12, 10, 0, 0, 0, time.UTC))
	phaseBegin := metav1.NewTime(now.Add(-5 * time.Minute))

	uo := &cloudv1.UpgradeOperation{
		Status: cloudv1.UpgradeOperationStatus{
			Reason: "Waiting for nodes",
			CurrentStep: &cloudv1.Step{
				LastProgressTime: &now,
				Phases: []cloudv1.StepPhase{
					{
						Name:             "wait-nodes-ready",
						BeginTime:        &phaseBegin,
						ProgressInfo:     "wait-nodes-ready=2/3",
						Done:             2,
						Total:            3,
						MaxDone:          2,
						LastProgressTime: &now,
					},
				},
			},
		},
	}

	resp := UpgradeOperation2PB(uo)
	require.Equal(t, "Waiting for nodes", resp.Message)
	require.NotNil(t, resp.LastProgressTime)
	require.Len(t, resp.Phases, 1)
	require.Equal(t, int32(2), resp.Phases[0].Done)
}

func TestUpgradeOperation2PB_fallbackToLastFinishedStep(t *testing.T) {
	now := metav1.NewTime(time.Date(2026, 6, 12, 10, 0, 0, 0, time.UTC))
	earlier := metav1.NewTime(now.Add(-10 * time.Minute))

	uo := &cloudv1.UpgradeOperation{
		Status: cloudv1.UpgradeOperationStatus{
			Reason: "All steps completed",
			FinishedSteps: cloudv1.Steps{
				{
					LastProgressTime: &earlier,
					Phases: []cloudv1.StepPhase{
						{Name: "old-phase", Done: 1, Total: 1},
					},
				},
				{
					LastProgressTime: &now,
					Phases: []cloudv1.StepPhase{
						{Name: "last-phase", Done: 3, Total: 3},
					},
				},
			},
		},
	}

	resp := UpgradeOperation2PB(uo)
	require.Equal(t, "All steps completed", resp.Message)
	require.NotNil(t, resp.LastProgressTime)
	require.Equal(t, now.UTC(), resp.LastProgressTime.AsTime().UTC())
	require.Len(t, resp.Phases, 1)
	require.Equal(t, "last-phase", resp.Phases[0].Name)
	require.Equal(t, int32(3), resp.Phases[0].Done)
}

func TestUpgradeOperation2PB_currentStepPrecedesFinishedSteps(t *testing.T) {
	now := metav1.NewTime(time.Date(2026, 6, 12, 10, 0, 0, 0, time.UTC))
	earlier := metav1.NewTime(now.Add(-10 * time.Minute))

	uo := &cloudv1.UpgradeOperation{
		Status: cloudv1.UpgradeOperationStatus{
			Reason: "In progress",
			CurrentStep: &cloudv1.Step{
				LastProgressTime: &now,
				Phases: []cloudv1.StepPhase{
					{Name: "current-phase", Done: 2, Total: 5},
				},
			},
			FinishedSteps: cloudv1.Steps{
				{
					LastProgressTime: &earlier,
					Phases: []cloudv1.StepPhase{
						{Name: "finished-phase", Done: 3, Total: 3},
					},
				},
			},
		},
	}

	resp := UpgradeOperation2PB(uo)
	require.Len(t, resp.Phases, 1)
	require.Equal(t, "current-phase", resp.Phases[0].Name)
	require.Equal(t, int32(2), resp.Phases[0].Done)
	require.Equal(t, now.UTC(), resp.LastProgressTime.AsTime().UTC())
}
