package source

import (
	"context"
	"testing"
	"time"

	"github.com/go-logr/logr"
	"github.com/stretchr/testify/assert"
	"github.com/tidbcloud/pkgv2/gormutil"
)

type mockQueue struct {
	items []any
}

func (m *mockQueue) Add(item any) {
	m.items = append(m.items, item)
}

func (m *mockQueue) AddAfter(item any, duration time.Duration) {}
func (m *mockQueue) AddRateLimited(item any)                   {}
func (m *mockQueue) Forget(item any)                           {}
func (m *mockQueue) NumRequeues(item any) int                  { return 0 }
func (m *mockQueue) Len() int                                  { return len(m.items) }
func (m *mockQueue) Get() (item any, shutdown bool)            { return nil, false }
func (m *mockQueue) Done(item any)                             {}
func (m *mockQueue) ShutDown()                                 {}
func (m *mockQueue) ShutDownWithDrain()                        {}
func (m *mockQueue) ShuttingDown() bool                        { return false }

func TestMysqlSource_Start(t *testing.T) {
	t.Run("starts with default TTL", func(t *testing.T) {
		ms := &MysqlSource{
			Logger: logr.Discard(),
			ConnCfg: &gormutil.Config{
				Host:     "localhost",
				Port:     3306,
				User:     "test",
				Password: "test",
				Database: "test",
			},
			PollingInterval: 100 * time.Millisecond,
			CleanupInterval: 200 * time.Millisecond,
		}

		queue := &mockQueue{}
		ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
		defer cancel()

		// This will fail to connect but we're testing the setup logic
		err := ms.Start(ctx, queue)
		assert.Error(t, err) // Expected to fail due to no real DB
	})

	t.Run("starts with custom TTL", func(t *testing.T) {
		ms := &MysqlSource{
			Logger: logr.Discard(),
			ConnCfg: &gormutil.Config{
				Host:     "localhost",
				Port:     3306,
				User:     "test",
				Password: "test",
				Database: "test",
			},
			PollingInterval: 100 * time.Millisecond,
			CleanupInterval: 200 * time.Millisecond,
			TTL:             5 * time.Minute,
		}

		queue := &mockQueue{}
		ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
		defer cancel()

		err := ms.Start(ctx, queue)
		assert.Error(t, err) // Expected to fail due to no real DB
	})
}
