package domain

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/dataflow-service-ng/app/repo/entity"
	"gorm.io/gorm"
)

func TestDataPipelineEntity2DomainDeepCopiesMutableFields(t *testing.T) {
	now := time.Date(2026, time.August, 2, 9, 0, 0, 0, time.UTC)
	pipelineEntity := &entity.DataPipeline{
		ID:                      101,
		TenantID:                102,
		ClusterID:               103,
		CreatorID:               104,
		UpdatedAt:               &now,
		Name:                    "test-pipeline",
		Status:                  entity.DataPipelineStatusPaused,
		ChangefeedSpecification: "standard-2",
		Params: entity.DataPipelineParams{
			Source: entity.DataPipelineSourceConfig{
				TableFilter: []string{"app.*", "audit.orders"},
			},
		},
		ExecutionPlan: entity.DataPipelineExecutionPlan{
			Incremental: &entity.DataPipelineIncrementalPlan{
				Engine: entity.DataPipelineIncrementalEngineTiCDC,
				Format: entity.DataPipelineIncrementalFormatCanalJSON,
			},
		},
		LastError: &entity.DataPipelineError{
			Code:       "TEST_ERROR",
			OccurredAt: &now,
		},
		Observation: entity.DataPipelineObservation{
			LastSucceededAt: &now,
			PollError: &entity.DataPipelineError{
				Code:       "TEST_POLL_ERROR",
				OccurredAt: &now,
			},
		},
		SoftDelete: entity.SoftDelete{
			DeletedAt: gorm.DeletedAt{Time: now, Valid: true},
		},
		Versioned: entity.Versioned{Versioning: 3},
	}

	pipeline := DataPipelineEntity2Domain(pipelineEntity)
	require.NotNil(t, pipeline)
	require.Equal(t, uint64(103), pipeline.ClusterID)
	require.Equal(t, "standard-2", pipeline.ChangefeedSpecification)
	require.Equal(t, 3, pipeline.Version)
	require.Equal(t, now, *pipeline.DeletedAt)

	pipeline.Params.Source.TableFilter[0] = "changed.*"
	pipeline.ExecutionPlan.Incremental.Format = "changed"
	pipeline.LastError.Code = "CHANGED"
	pipeline.Observation.PollError.Code = "CHANGED"
	*pipeline.UpdatedAt = now.Add(time.Hour)

	require.Equal(t, "app.*", pipelineEntity.Params.Source.TableFilter[0])
	require.Equal(t, entity.DataPipelineIncrementalFormatCanalJSON, pipelineEntity.ExecutionPlan.Incremental.Format)
	require.Equal(t, "TEST_ERROR", pipelineEntity.LastError.Code)
	require.Equal(t, "TEST_POLL_ERROR", pipelineEntity.Observation.PollError.Code)
	require.Equal(t, now, *pipelineEntity.UpdatedAt)
}

func TestDataPipelineEntity2DomainNil(t *testing.T) {
	require.Nil(t, DataPipelineEntity2Domain(nil))
}
