package database

import (
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"github.com/tidbcloud/AgentTeam/internal/store/repocache"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

// publicRepositoryCacheBeforeGenerations mirrors the AutoMigrate schema that
// existed before active_generation and revision fenced immutable generations.
type publicRepositoryCacheBeforeGenerations struct {
	ID                  string     `gorm:"primaryKey;size:64"`
	NormalizedRemoteURL string     `gorm:"column:normalized_remote_url;size:768;not null;uniqueIndex"`
	DisplayRemoteURL    string     `gorm:"column:display_remote_url;size:1024;not null"`
	Status              string     `gorm:"size:32;not null;default:'pending';index"`
	AutoRefreshEnabled  bool       `gorm:"not null;default:false;index"`
	RefreshIntervalSecs int        `gorm:"column:refresh_interval_seconds;not null;default:86400"`
	LastSyncAt          *time.Time `gorm:"index"`
	LastSuccessAt       *time.Time `gorm:"index"`
	NextSyncAt          *time.Time `gorm:"index"`
	LastCommit          string     `gorm:"size:255;not null;default:''"`
	LastError           string     `gorm:"type:text;not null"`
	Info                string     `gorm:"column:info;type:json;not null"`
	LeaseOwner          string     `gorm:"size:128;not null;default:''"`
	LeaseUntil          *time.Time `gorm:"index"`
	CreatedBy           string     `gorm:"size:64;not null"`
	UpdatedBy           string     `gorm:"size:64;not null"`
	CreatedAt           time.Time  `gorm:"not null"`
	UpdatedAt           time.Time  `gorm:"not null;index"`
}

func (publicRepositoryCacheBeforeGenerations) TableName() string {
	return "public_repository_caches"
}

func legacyPublicRepositoryCacheFixture(now time.Time) publicRepositoryCacheBeforeGenerations {
	lastSuccess := now.Add(-time.Hour)
	return publicRepositoryCacheBeforeGenerations{
		ID:                  "prc_legacy",
		NormalizedRemoteURL: "https://example.com/org/repo.git",
		DisplayRemoteURL:    "https://example.com/org/repo.git",
		Status:              repocache.StatusReady,
		RefreshIntervalSecs: 3600,
		LastSuccessAt:       &lastSuccess,
		LastCommit:          "legacy-commit",
		LastError:           "",
		Info:                `{"sizeBytes":42}`,
		CreatedBy:           "ops",
		UpdatedBy:           "ops",
		CreatedAt:           now,
		UpdatedAt:           now,
	}
}

func TestMigrateAddsGenerationAndRevisionToLegacyPublicRepositoryCacheRows(t *testing.T) {
	db, err := gorm.Open(sqlite.Open("file:"+t.Name()+"?mode=memory&cache=shared"), &gorm.Config{})
	require.NoError(t, err)
	sqlDB, err := db.DB()
	require.NoError(t, err)
	t.Cleanup(func() { require.NoError(t, sqlDB.Close()) })
	require.NoError(t, db.AutoMigrate(&publicRepositoryCacheBeforeGenerations{}))
	legacy := legacyPublicRepositoryCacheFixture(time.Now().UTC())
	require.NoError(t, db.Create(&legacy).Error)
	require.False(t, db.Migrator().HasColumn(&repocache.Cache{}, "ActiveGeneration"))
	require.False(t, db.Migrator().HasColumn(&repocache.Cache{}, "Revision"))

	require.NoError(t, Migrate(db))
	require.True(t, db.Migrator().HasColumn(&repocache.Cache{}, "ActiveGeneration"))
	require.True(t, db.Migrator().HasColumn(&repocache.Cache{}, "Revision"))
	var migrated repocache.Cache
	require.NoError(t, db.First(&migrated, "id = ?", "prc_legacy").Error)
	require.Empty(t, migrated.ActiveGeneration)
	require.Equal(t, uint64(0), migrated.Revision)
	require.Equal(t, repocache.StatusReady, migrated.Status)
	require.Equal(t, "legacy-commit", migrated.LastCommit)
	require.NotNil(t, migrated.LastSuccessAt)
}
