package pimport

import (
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/dataflow-service-ng/app/event_bus/publisher/center"
	"github.com/tidbcloud/dataflow-service-ng/app/repo/entity"
	"github.com/tidbcloud/eventbus-datastruct/event"
)

func TestConvertImportIntoToDisplayEvent(t *testing.T) {
	task := &entity.ImportIntoTask{
		Updatable: entity.Updatable{Base: entity.Base{ID: 42}},
		Name:      "imp-1",
		Status:    entity.ImportIntoStatusPreparing,
		ClusterID: 100,
		ProjectID: 200,
		TenantID:  300,
		CreatorID: 7,
		Creator:   "user@example.com",
		TotalSize: 1024,
	}

	ev := convertImportIntoToDisplayEvent(task)
	require.NotNil(t, ev)
	require.Equal(t, string(entity.ImportDisplayType), ev.DisplayEventType)
	require.Equal(t, event.EventStatusStarted, ev.DisplayStatus)
	require.Equal(t, "42", ev.ContextID)
	require.Equal(t, uint64(100), ev.ClusterID)
	require.Equal(t, uint64(200), ev.ProjectID)
	require.Equal(t, uint64(300), ev.TenantID)
	require.Equal(t, uint64(7), ev.AuthorID)

	detail, ok := ev.Detail.(*center.ImportIntoMsg)
	require.True(t, ok)
	require.Equal(t, uint64(42), detail.ImportId)
	require.Equal(t, uint64(1024), detail.TotalSize)
}

func TestConvertImportIntoTerminalStatuses(t *testing.T) {
	tests := map[string]struct {
		status         entity.ImportIntoStatus
		displayStatus  event.EventStatus
		expectNilEvent bool
	}{
		"importing": {status: entity.ImportIntoStatusImporting, expectNilEvent: true},
		"scaling":   {status: entity.ImportIntoStatusScalingUp, expectNilEvent: true},
		"completed": {status: entity.ImportIntoStatusCompleted, displayStatus: event.EventStatusSucceeded},
		"failed":    {status: entity.ImportIntoStatusFailed, displayStatus: event.EventStatusFailed},
		"canceled":  {status: entity.ImportIntoStatusCanceled, displayStatus: event.EventStatusCanceled},
		"canceling": {status: entity.ImportIntoStatusCanceling, expectNilEvent: true},
	}
	for name, tc := range tests {
		t.Run(name, func(t *testing.T) {
			ev := convertImportIntoToDisplayEvent(&entity.ImportIntoTask{
				Updatable: entity.Updatable{Base: entity.Base{ID: 1}},
				Status:    tc.status,
				Name:      "n",
			})
			if tc.expectNilEvent {
				require.Nil(t, ev)
				return
			}
			require.NotNil(t, ev)
			require.Equal(t, tc.displayStatus, ev.DisplayStatus)
		})
	}
}
