package database_test

import (
	"context"
	"fmt"
	"os"
	"testing"
	"time"

	"github.com/jackc/pgx/v5"
	"github.com/modelcontextprotocol/registry/internal/database"
	apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0"
	"github.com/modelcontextprotocol/registry/pkg/model"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

const testVersion100 = "1.0.0"

func TestPostgreSQL_CreateServer(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	tests := []struct {
		name         string
		serverJSON   *apiv0.ServerJSON
		officialMeta *apiv0.RegistryExtensions
		expectError  bool
		errorType    error
	}{
		{
			name: "successful server creation",
			serverJSON: &apiv0.ServerJSON{
				Name:        "com.example/test-server",
				Description: "A test server",
				Version:     "1.0.0",
				Remotes: []model.Transport{
					{Type: "http", URL: "https://api.example.com/mcp"},
				},
			},
			officialMeta: &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			},
			expectError: false,
		},
		{
			name: "duplicate server version should fail",
			serverJSON: &apiv0.ServerJSON{
				Name:        "com.example/duplicate-server",
				Description: "A duplicate test server",
				Version:     "1.0.0",
			},
			officialMeta: &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			},
			expectError: true,
			// Note: Expecting generic database error for constraint violation
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			// Create the first server to test duplicates
			if tt.name == "duplicate server version should fail" {
				_, err := db.CreateServer(ctx, nil, tt.serverJSON, tt.officialMeta)
				require.NoError(t, err, "First creation should succeed")
			}

			result, err := db.CreateServer(ctx, nil, tt.serverJSON, tt.officialMeta)

			if tt.expectError {
				assert.Error(t, err)
				if tt.errorType != nil {
					assert.ErrorIs(t, err, tt.errorType)
				}
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, tt.serverJSON.Name, result.Server.Name)
				assert.Equal(t, tt.serverJSON.Version, result.Server.Version)
				assert.Equal(t, tt.serverJSON.Description, result.Server.Description)
				assert.NotNil(t, result.Meta.Official)
				assert.Equal(t, tt.officialMeta.Status, result.Meta.Official.Status)
				assert.Equal(t, tt.officialMeta.IsLatest, result.Meta.Official.IsLatest)
			}
		})
	}
}

func TestPostgreSQL_GetServerByName(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Setup test data
	serverJSON := &apiv0.ServerJSON{
		Name:        "com.example/get-test-server",
		Description: "A server for get testing",
		Version:     "1.0.0",
	}
	officialMeta := &apiv0.RegistryExtensions{
		Status:          model.StatusActive,
		StatusChangedAt: timeNow,
		PublishedAt:     timeNow,
		UpdatedAt:       timeNow,
		IsLatest:        true,
	}

	// Create the server
	_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
	require.NoError(t, err)

	tests := []struct {
		name        string
		serverName  string
		expectError bool
		errorType   error
	}{
		{
			name:       "get existing server",
			serverName: "com.example/get-test-server",
		},
		{
			name:        "get non-existent server",
			serverName:  "com.example/non-existent",
			expectError: true,
			errorType:   database.ErrNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := db.GetServerByName(ctx, nil, tt.serverName, false)

			if tt.expectError {
				assert.Error(t, err)
				if tt.errorType != nil {
					assert.ErrorIs(t, err, tt.errorType)
				}
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, tt.serverName, result.Server.Name)
				assert.NotNil(t, result.Meta.Official)
			}
		})
	}
}

func TestPostgreSQL_GetServerByNameAndVersion(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Setup test data with multiple versions
	serverName := "com.example/version-test-server"
	versions := []string{"1.0.0", "1.1.0", "2.0.0"}

	for i, version := range versions {
		serverJSON := &apiv0.ServerJSON{
			Name:        serverName,
			Description: "A server for version testing",
			Version:     version,
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        i == len(versions)-1, // Only last version is latest
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	tests := []struct {
		name        string
		serverName  string
		version     string
		expectError bool
		errorType   error
	}{
		{
			name:       "get existing server version",
			serverName: serverName,
			version:    "1.1.0",
		},
		{
			name:        "get non-existent version",
			serverName:  serverName,
			version:     "3.0.0",
			expectError: true,
			errorType:   database.ErrNotFound,
		},
		{
			name:        "get non-existent server",
			serverName:  "com.example/non-existent",
			version:     "1.0.0",
			expectError: true,
			errorType:   database.ErrNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := db.GetServerByNameAndVersion(ctx, nil, tt.serverName, tt.version, false)

			if tt.expectError {
				assert.Error(t, err)
				if tt.errorType != nil {
					assert.ErrorIs(t, err, tt.errorType)
				}
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, tt.serverName, result.Server.Name)
				assert.Equal(t, tt.version, result.Server.Version)
				assert.NotNil(t, result.Meta.Official)
			}
		})
	}
}

func TestPostgreSQL_ListServers(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()

	// Setup test data
	testServers := []struct {
		name        string
		version     string
		status      model.Status
		remoteURL   string
		isLatest    bool
		publishedAt time.Time
	}{
		{
			name:        "com.example/server-a",
			version:     "1.0.0",
			status:      model.StatusActive,
			remoteURL:   "https://api-a.example.com/mcp",
			isLatest:    true,
			publishedAt: time.Now().Add(-2 * time.Hour),
		},
		{
			name:        "com.example/server-b",
			version:     "2.0.0",
			status:      model.StatusActive,
			remoteURL:   "https://api-b.example.com/mcp",
			isLatest:    true,
			publishedAt: time.Now().Add(-1 * time.Hour),
		},
		{
			name:        "com.example/server-c",
			version:     "1.0.0",
			status:      model.StatusDeprecated,
			remoteURL:   "https://api-c.example.com/mcp",
			isLatest:    true,
			publishedAt: time.Now().Add(-30 * time.Minute),
		},
	}

	// Create test servers
	for _, server := range testServers {
		serverJSON := &apiv0.ServerJSON{
			Name:        server.name,
			Description: "Test server for listing",
			Version:     server.version,
			Remotes: []model.Transport{
				{Type: "http", URL: server.remoteURL},
			},
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          server.status,
			StatusChangedAt: server.publishedAt,
			PublishedAt:     server.publishedAt,
			UpdatedAt:       server.publishedAt,
			IsLatest:        server.isLatest,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	tests := []struct {
		name          string
		filter        *database.ServerFilter
		cursor        string
		limit         int
		expectedCount int
		expectedNames []string
		expectError   bool
	}{
		{
			name:          "list all servers",
			filter:        nil,
			limit:         10,
			expectedCount: 3,
			expectedNames: []string{"com.example/server-a", "com.example/server-b", "com.example/server-c"},
		},
		{
			name: "filter by name",
			filter: &database.ServerFilter{
				Name: stringPtr("com.example/server-a"),
			},
			limit:         10,
			expectedCount: 1,
			expectedNames: []string{"com.example/server-a"},
		},
		{
			name: "filter by remote URL",
			filter: &database.ServerFilter{
				RemoteURL: stringPtr("https://api-b.example.com/mcp"),
			},
			limit:         10,
			expectedCount: 1,
			expectedNames: []string{"com.example/server-b"},
		},
		{
			name: "filter by substring name",
			filter: &database.ServerFilter{
				SubstringName: stringPtr("server-"),
			},
			limit:         10,
			expectedCount: 3,
		},
		{
			name: "filter by version",
			filter: &database.ServerFilter{
				Version: stringPtr("1.0.0"),
			},
			limit:         10,
			expectedCount: 2,
		},
		{
			name: "filter by isLatest",
			filter: &database.ServerFilter{
				IsLatest: boolPtr(true),
			},
			limit:         10,
			expectedCount: 3,
		},
		{
			name: "filter by updatedSince",
			filter: &database.ServerFilter{
				UpdatedSince: timePtr(time.Now().Add(-45 * time.Minute)),
			},
			limit:         10,
			expectedCount: 1, // Only server-c was updated in the last 45 minutes
		},
		{
			name:          "test pagination with limit",
			filter:        nil,
			limit:         2,
			expectedCount: 2,
		},
		{
			name:   "test cursor pagination",
			filter: nil,
			cursor: "com.example/server-a",
			limit:  10,
			// Should return servers after 'server-a' alphabetically
			expectedCount: 2,
			expectedNames: []string{"com.example/server-b", "com.example/server-c"},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			results, nextCursor, err := db.ListServers(ctx, nil, tt.filter, tt.cursor, tt.limit)

			if tt.expectError {
				assert.Error(t, err)
				return
			}

			assert.NoError(t, err)
			assert.Len(t, results, tt.expectedCount)

			if len(tt.expectedNames) > 0 {
				actualNames := make([]string, len(results))
				for i, result := range results {
					actualNames[i] = result.Server.Name
				}
				assert.Subset(t, tt.expectedNames, actualNames)
			}

			// Test cursor behavior
			if tt.limit < len(testServers) && len(results) == tt.limit {
				assert.NotEmpty(t, nextCursor, "Should return next cursor when results are limited")
			}
		})
	}
}

func TestPostgreSQL_UpdateServer(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Setup test data
	serverName := "com.example/update-test-server"
	version := testVersion100
	serverJSON := &apiv0.ServerJSON{
		Name:        serverName,
		Description: "Original description",
		Version:     version,
	}
	officialMeta := &apiv0.RegistryExtensions{
		Status:          model.StatusActive,
		StatusChangedAt: timeNow,
		PublishedAt:     timeNow,
		UpdatedAt:       timeNow,
		IsLatest:        true,
	}

	_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
	require.NoError(t, err)

	tests := []struct {
		name          string
		serverName    string
		version       string
		updatedServer *apiv0.ServerJSON
		expectError   bool
		errorType     error
	}{
		{
			name:       "successful server update",
			serverName: serverName,
			version:    version,
			updatedServer: &apiv0.ServerJSON{
				Name:        serverName,
				Description: "Updated description",
				Version:     version,
				Remotes: []model.Transport{
					{Type: "http", URL: "https://updated.example.com/mcp"},
				},
			},
		},
		{
			name:       "update non-existent server",
			serverName: "com.example/non-existent",
			version:    testVersion100,
			updatedServer: &apiv0.ServerJSON{
				Name:        "com.example/non-existent",
				Description: "Should fail",
				Version:     testVersion100,
			},
			expectError: true,
			errorType:   database.ErrNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := db.UpdateServer(ctx, nil, tt.serverName, tt.version, tt.updatedServer)

			if tt.expectError {
				assert.Error(t, err)
				if tt.errorType != nil {
					assert.ErrorIs(t, err, tt.errorType)
				}
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, tt.updatedServer.Description, result.Server.Description)
				assert.NotNil(t, result.Meta.Official)
				assert.NotZero(t, result.Meta.Official.UpdatedAt)
			}
		})
	}
}

func TestPostgreSQL_SetServerStatus(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Setup test data
	serverName := "com.example/status-test-server"
	version := testVersion100
	serverJSON := &apiv0.ServerJSON{
		Name:        serverName,
		Description: "A server for status testing",
		Version:     version,
	}
	officialMeta := &apiv0.RegistryExtensions{
		Status:          model.StatusActive,
		StatusChangedAt: timeNow,
		PublishedAt:     timeNow,
		UpdatedAt:       timeNow,
		IsLatest:        true,
	}

	_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
	require.NoError(t, err)

	tests := []struct {
		name        string
		serverName  string
		version     string
		newStatus   string
		expectError bool
		errorType   error
	}{
		{
			name:       "active to deprecated",
			serverName: serverName,
			version:    version,
			newStatus:  string(model.StatusDeprecated),
		},
		{
			name:        "invalid status",
			serverName:  serverName,
			version:     version,
			newStatus:   "invalid_status",
			expectError: true,
		},
		{
			name:        "non-existent server",
			serverName:  "com.example/non-existent",
			version:     "1.0.1",
			newStatus:   string(model.StatusDeprecated),
			expectError: true,
			errorType:   database.ErrNotFound,
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			result, err := db.SetServerStatus(ctx, nil, tt.serverName, tt.version, model.Status(tt.newStatus), nil)

			if tt.expectError {
				assert.Error(t, err)
				if tt.errorType != nil {
					assert.ErrorIs(t, err, tt.errorType)
				}
				assert.Nil(t, result)
			} else {
				assert.NoError(t, err)
				assert.NotNil(t, result)
				assert.Equal(t, model.Status(tt.newStatus), result.Meta.Official.Status)
				assert.NotZero(t, result.Meta.Official.UpdatedAt)
			}
		})
	}
}

func TestPostgreSQL_StatusChangedAtBehavior(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()

	t.Run("status_changed_at updates when status changes", func(t *testing.T) {
		timeNow := time.Now()
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/status-changed-at-test",
			Description: "Test server",
			Version:     "1.0.0",
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Wait a bit to ensure time difference
		time.Sleep(10 * time.Millisecond)

		// Change status from active to deprecated
		result, err := db.SetServerStatus(ctx, nil, serverJSON.Name, serverJSON.Version, model.StatusDeprecated, nil)
		require.NoError(t, err)

		assert.Equal(t, model.StatusDeprecated, result.Meta.Official.Status)
		assert.True(t, result.Meta.Official.StatusChangedAt.After(timeNow), "status_changed_at should be updated")
	})

	t.Run("status_changed_at preserved when only message changes", func(t *testing.T) {
		timeNow := time.Now()
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/message-only-test",
			Description: "Test server",
			Version:     "1.0.0",
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusDeprecated,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Wait a bit to ensure time difference
		time.Sleep(10 * time.Millisecond)

		// Update only the message, keep status the same
		newMessage := "Updated message"
		result, err := db.SetServerStatus(ctx, nil, serverJSON.Name, serverJSON.Version, model.StatusDeprecated, &newMessage)
		require.NoError(t, err)

		assert.Equal(t, model.StatusDeprecated, result.Meta.Official.Status)
		assert.Equal(t, "Updated message", *result.Meta.Official.StatusMessage)
		// status_changed_at should NOT be updated since status didn't change
		assert.True(t, result.Meta.Official.StatusChangedAt.Before(result.Meta.Official.UpdatedAt), "status_changed_at should be older than updated_at")
	})
}

func TestPostgreSQL_TransactionHandling(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()

	t.Run("successful transaction", func(t *testing.T) {
		timeNow := time.Now()
		err := db.InTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error {
			serverJSON := &apiv0.ServerJSON{
				Name:        "com.example/transaction-success",
				Description: "Transaction test server",
				Version:     "1.0.0",
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			}

			_, err := db.CreateServer(ctx, tx, serverJSON, officialMeta)
			return err
		})

		assert.NoError(t, err)

		// Verify server was created
		result, err := db.GetServerByName(ctx, nil, "com.example/transaction-success", false)
		assert.NoError(t, err)
		assert.NotNil(t, result)
	})

	t.Run("failed transaction rollback", func(t *testing.T) {
		timeNow := time.Now()
		err := db.InTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error {
			serverJSON := &apiv0.ServerJSON{
				Name:        "com.example/transaction-rollback",
				Description: "Transaction rollback test server",
				Version:     "1.0.0",
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			}

			_, err := db.CreateServer(ctx, tx, serverJSON, officialMeta)
			if err != nil {
				return err
			}

			// Force an error to trigger rollback
			return assert.AnError
		})

		assert.Error(t, err)
		assert.Equal(t, assert.AnError, err)

		// Verify server was NOT created due to rollback
		result, err := db.GetServerByName(ctx, nil, "com.example/transaction-rollback", false)
		assert.Error(t, err)
		assert.ErrorIs(t, err, database.ErrNotFound)
		assert.Nil(t, result)
	})
}

func TestPostgreSQL_ConcurrencyAndLocking(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()

	serverName := "com.example/concurrent-server"

	// Test advisory locking prevents concurrent publishes
	t.Run("advisory locking prevents race conditions", func(t *testing.T) {
		published := make(chan bool, 2)
		errors := make(chan error, 2)

		// Launch two concurrent publish operations
		for i := 0; i < 2; i++ {
			go func(version string) {
				timeNow := time.Now()
				err := db.InTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error {
					// Acquire lock
					if err := db.AcquirePublishLock(ctx, tx, serverName); err != nil {
						return err
					}

					// Simulate some processing time
					time.Sleep(100 * time.Millisecond)

					serverJSON := &apiv0.ServerJSON{
						Name:        serverName,
						Description: "Concurrent test server",
						Version:     version,
					}
					officialMeta := &apiv0.RegistryExtensions{
						Status:          model.StatusActive,
						StatusChangedAt: timeNow,
						PublishedAt:     timeNow,
						UpdatedAt:       timeNow,
						IsLatest:        true,
					}

					_, err := db.CreateServer(ctx, tx, serverJSON, officialMeta)
					if err != nil {
						return err
					}

					published <- true
					return nil
				})
				errors <- err
			}(time.Now().Format("20060102150405.000000"))
		}

		// Wait for both goroutines to complete
		err1 := <-errors
		err2 := <-errors

		// One should succeed, one should wait (or fail if timeout)
		successCount := 0
		if err1 == nil {
			successCount++
		}
		if err2 == nil {
			successCount++
		}

		// At least one should succeed (both can succeed if advisory lock works properly)
		assert.GreaterOrEqual(t, successCount, 1, "At least one concurrent operation should succeed")

		close(published)
		close(errors)
	})
}

func TestPostgreSQL_HelperMethods(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	serverName := "com.example/helper-test-server"

	// Setup test data with multiple versions
	versions := []string{"1.0.0", "1.1.0", "2.0.0"}
	for _, version := range versions {
		serverJSON := &apiv0.ServerJSON{
			Name:        serverName,
			Description: "Helper methods test server",
			Version:     version,
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        version == "2.0.0",
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	t.Run("CountServerVersions", func(t *testing.T) {
		count, err := db.CountServerVersions(ctx, nil, serverName)
		assert.NoError(t, err)
		assert.Equal(t, 3, count)

		// Test non-existent server
		count, err = db.CountServerVersions(ctx, nil, "com.example/non-existent")
		assert.NoError(t, err)
		assert.Equal(t, 0, count)
	})

	t.Run("CheckVersionExists", func(t *testing.T) {
		exists, err := db.CheckVersionExists(ctx, nil, serverName, "1.1.0")
		assert.NoError(t, err)
		assert.True(t, exists)

		exists, err = db.CheckVersionExists(ctx, nil, serverName, "3.0.0")
		assert.NoError(t, err)
		assert.False(t, exists)
	})

	t.Run("GetCurrentLatestVersion", func(t *testing.T) {
		latest, err := db.GetCurrentLatestVersion(ctx, nil, serverName)
		assert.NoError(t, err)
		assert.NotNil(t, latest)
		assert.Equal(t, "2.0.0", latest.Server.Version)
		assert.True(t, latest.Meta.Official.IsLatest)
	})

	t.Run("GetAllVersionsByServerName", func(t *testing.T) {
		allVersions, err := db.GetAllVersionsByServerName(ctx, nil, serverName, false)
		assert.NoError(t, err)
		assert.Len(t, allVersions, 3)

		// Check versions are present
		versionSet := make(map[string]bool)
		for _, server := range allVersions {
			versionSet[server.Server.Version] = true
		}
		for _, expectedVersion := range versions {
			assert.True(t, versionSet[expectedVersion], "Version %s should be present", expectedVersion)
		}
	})

	t.Run("UnmarkAsLatest", func(t *testing.T) {
		err := db.UnmarkAsLatest(ctx, nil, serverName)
		assert.NoError(t, err)

		// Verify no version is marked as latest
		latest, err := db.GetCurrentLatestVersion(ctx, nil, serverName)
		assert.Error(t, err)
		assert.ErrorIs(t, err, database.ErrNotFound)
		assert.Nil(t, latest)
	})
}

func TestPostgreSQL_EdgeCases(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	t.Run("input validation", func(t *testing.T) {
		// Test nil inputs
		_, err := db.CreateServer(ctx, nil, nil, nil)
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "serverJSON and officialMeta are required")

		// Test empty required fields
		_, err = db.CreateServer(ctx, nil, &apiv0.ServerJSON{}, &apiv0.RegistryExtensions{})
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "server name and version are required")
	})

	t.Run("database constraints", func(t *testing.T) {
		// Test server name format constraint (should be caught by database constraint)
		invalidServer := &apiv0.ServerJSON{
			Name:        "invalid-name-format", // Missing namespace/name format
			Description: "Invalid server",
			Version:     "1.0.0",
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, invalidServer, officialMeta)
		assert.Error(t, err, "Should fail due to server name format constraint")
	})

	t.Run("pagination edge cases", func(t *testing.T) {
		// Test pagination with no results
		results, cursor, err := db.ListServers(ctx, nil, &database.ServerFilter{
			Name: stringPtr("com.example/non-existent-server"),
		}, "", 10)
		assert.NoError(t, err)
		assert.Empty(t, results)
		assert.Empty(t, cursor)

		// Test pagination with limit 0 (should use default)
		_, _, err = db.ListServers(ctx, nil, nil, "", 0)
		assert.NoError(t, err)
		// Should still work with default limit
	})

	t.Run("complex filtering", func(t *testing.T) {
		// Setup test data
		serverName := "com.example/complex-filter-server"
		testTime := time.Now().Add(-1 * time.Hour)

		_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
			Name:        serverName,
			Description: "Complex filter test server",
			Version:     "1.0.0",
			Remotes: []model.Transport{
				{Type: "streamable-http", URL: "https://complex.example.com/mcp"},
			},
		}, &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: testTime,
			PublishedAt:     testTime,
			UpdatedAt:       testTime,
			IsLatest:        true,
		})
		require.NoError(t, err)

		// Test multiple filters combined
		filter := &database.ServerFilter{
			SubstringName: stringPtr("complex"),
			UpdatedSince:  timePtr(testTime.Add(-30 * time.Minute)),
			IsLatest:      boolPtr(true),
			Version:       stringPtr("1.0.0"),
		}

		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		assert.NoError(t, err)
		assert.Len(t, results, 1)
		assert.Equal(t, serverName, results[0].Server.Name)
	})

	t.Run("status transitions", func(t *testing.T) {
		serverName := "com.example/status-transition-server"
		version := "1.0.2"

		// Create server
		_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
			Name:        serverName,
			Description: "Status transition test",
			Version:     version,
		}, &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		})
		require.NoError(t, err)

		// Test all valid status transitions
		statuses := []string{
			string(model.StatusDeprecated),
			string(model.StatusDeleted),
			string(model.StatusActive), // Can transition back
		}

		for _, status := range statuses {
			result, err := db.SetServerStatus(ctx, nil, serverName, version, model.Status(status), nil)
			assert.NoError(t, err, "Should allow transition to %s", status)
			assert.Equal(t, model.Status(status), result.Meta.Official.Status)
		}
	})

	// Test status transitions with additional fields
	t.Run("status transitions with message", func(t *testing.T) {
		testServerName := "com.example/status-fields-test"
		testVersion := "1.0.0"

		// Create a test server
		_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
			Name:        testServerName,
			Description: "Status fields test",
			Version:     testVersion,
		}, &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		})
		require.NoError(t, err)

		statusMessage := "This server has been deprecated. Please use the new version."

		// Test setting status with message
		result, err := db.SetServerStatus(ctx, nil, testServerName, testVersion, model.StatusDeprecated, &statusMessage)
		assert.NoError(t, err)
		assert.Equal(t, model.StatusDeprecated, result.Meta.Official.Status)
		assert.NotNil(t, result.Meta.Official.StatusMessage)
		assert.Equal(t, statusMessage, *result.Meta.Official.StatusMessage)
		assert.NotZero(t, result.Meta.Official.StatusChangedAt)

		// Test clearing status message
		result, err = db.SetServerStatus(ctx, nil, testServerName, testVersion, model.StatusActive, nil)
		assert.NoError(t, err)
		assert.Equal(t, model.StatusActive, result.Meta.Official.Status)
		assert.Nil(t, result.Meta.Official.StatusMessage)
	})

	// Test comprehensive status transitions as per user requirements
	t.Run("comprehensive status transitions", func(t *testing.T) {
		testServerName := "com.example/comprehensive-transitions-test"
		testVersion := "1.0.0"

		// Create a test server in active status
		_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
			Name:        testServerName,
			Description: "Comprehensive transitions test",
			Version:     testVersion,
		}, &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		})
		require.NoError(t, err)

		// Define all valid transitions based on user requirements
		transitionTests := []struct {
			name        string
			fromStatus  model.Status
			toStatus    model.Status
			description string
		}{
			// Active ↔ Deprecated
			{"active to deprecated", model.StatusActive, model.StatusDeprecated, "Deprecating active server"},
			{"deprecated to active", model.StatusDeprecated, model.StatusActive, "Reactivating deprecated server"},

			// Active ↔ Deleted
			{"active to deleted", model.StatusActive, model.StatusDeleted, "Deleting active server"},
			{"deleted to active", model.StatusDeleted, model.StatusActive, "Restoring to active server"},

			// Deprecated ↔ Deleted
			{"deprecated to deleted", model.StatusDeprecated, model.StatusDeleted, "Deleting deprecated server"},
			{"deleted to deprecated", model.StatusDeleted, model.StatusDeprecated, "Moving deleted to deprecated"},
		}

		for _, tt := range transitionTests {
			t.Run(tt.name, func(t *testing.T) {
				// First ensure the server is in the expected starting status
				if tt.fromStatus != model.StatusActive {
					_, err := db.SetServerStatus(ctx, nil, testServerName, testVersion, tt.fromStatus, nil)
					require.NoError(t, err, "failed to set initial status to %s", tt.fromStatus)
				}

				// Verify the server is in the expected starting status
				// Use includeDeleted=true since we test transitions involving deleted status
				currentServer, err := db.GetServerByNameAndVersion(ctx, nil, testServerName, testVersion, true)
				require.NoError(t, err)
				assert.Equal(t, tt.fromStatus, currentServer.Meta.Official.Status, "server should be in %s status before transition", tt.fromStatus)

				// Perform the transition
				result, err := db.SetServerStatus(ctx, nil, testServerName, testVersion, tt.toStatus, &tt.description)
				assert.NoError(t, err, "should allow transition from %s to %s", tt.fromStatus, tt.toStatus)
				assert.NotNil(t, result)
				assert.Equal(t, tt.toStatus, result.Meta.Official.Status, "status should be %s after transition", tt.toStatus)
				assert.NotNil(t, result.Meta.Official.StatusMessage)
				assert.Equal(t, tt.description, *result.Meta.Official.StatusMessage)
				assert.NotZero(t, result.Meta.Official.StatusChangedAt)
			})
		}
	})
}

func TestPostgreSQL_PerformanceScenarios(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	t.Run("many versions management", func(t *testing.T) {
		serverName := "com.example/many-versions-server"

		// Create many versions (but stay under the limit)
		versionCount := 50
		for i := 0; i < versionCount; i++ {
			_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
				Name:        serverName,
				Description: fmt.Sprintf("Version %d", i),
				Version:     fmt.Sprintf("1.0.%d", i),
			}, &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        i == versionCount-1, // Only last one is latest
			})
			require.NoError(t, err)
		}

		// Test counting versions
		count, err := db.CountServerVersions(ctx, nil, serverName)
		assert.NoError(t, err)
		assert.Equal(t, versionCount, count)

		// Test getting all versions
		allVersions, err := db.GetAllVersionsByServerName(ctx, nil, serverName, false)
		assert.NoError(t, err)
		assert.Len(t, allVersions, versionCount)

		// Test only one is marked as latest
		latestCount := 0
		for _, version := range allVersions {
			if version.Meta.Official.IsLatest {
				latestCount++
			}
		}
		assert.Equal(t, 1, latestCount)
	})

	t.Run("large result pagination", func(t *testing.T) {
		// Create multiple servers for pagination testing
		serverCount := 25
		for i := 0; i < serverCount; i++ {
			_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
				Name:        fmt.Sprintf("com.example/pagination-server-%02d", i),
				Description: "Pagination test server",
				Version:     "1.0.0",
			}, &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			})
			require.NoError(t, err)
		}

		// Test paginated retrieval
		allResults := []*apiv0.ServerResponse{}
		cursor := ""
		pageSize := 10

		for {
			results, nextCursor, err := db.ListServers(ctx, nil, nil, cursor, pageSize)
			assert.NoError(t, err)
			allResults = append(allResults, results...)

			if nextCursor == "" || len(results) < pageSize {
				break
			}
			cursor = nextCursor
		}

		// Should have retrieved all servers including the ones we just created
		assert.GreaterOrEqual(t, len(allResults), serverCount)
	})

	t.Run("compound cursor across versions of same server", func(t *testing.T) {
		// Insert multiple versions of two servers so cursor pagination has to
		// correctly seek across the (server_name, version) boundary. This is the
		// case that the row-constructor cursor predicate `(server_name, version) > ($1, $2)`
		// has to handle — the OR-decomposed form had the same semantics but a
		// linear-scan plan; this test pins the semantic behaviour so a future
		// rewrite can't silently break it.
		serverA := "com.example/cursor-test-a"
		serverB := "com.example/cursor-test-b"
		versionsA := []string{"1.0.0", "2.0.0", "3.0.0"}
		versionsB := []string{"1.0.0", "2.0.0"}

		// First mark the latest version of each as latest=true; older ones false
		// so the pkey + uniqueness constraints are satisfied.
		mkServer := func(name, version string, isLatest bool) {
			_, err := db.CreateServer(ctx, nil, &apiv0.ServerJSON{
				Name: name, Description: "compound cursor test", Version: version,
			}, &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow, PublishedAt: timeNow, UpdatedAt: timeNow,
				IsLatest: isLatest,
			})
			require.NoError(t, err)
		}
		for i, v := range versionsA {
			mkServer(serverA, v, i == len(versionsA)-1)
		}
		for i, v := range versionsB {
			mkServer(serverB, v, i == len(versionsB)-1)
		}

		// Filter to just the two servers we just created so unrelated rows in the
		// shared test DB don't bleed in.
		filterTo := func(rs []*apiv0.ServerResponse) []*apiv0.ServerResponse {
			out := make([]*apiv0.ServerResponse, 0, len(rs))
			for _, r := range rs {
				if r.Server.Name == serverA || r.Server.Name == serverB {
					out = append(out, r)
				}
			}
			return out
		}

		// Cursor at (serverA, "1.0.0") must skip 1.0.0 and return 2.0.0, 3.0.0,
		// then both versions of serverB. Specifically tests the compound predicate:
		// without it, the OR form would still skip 1.0.0 correctly but the version
		// boundary of (serverA, "3.0.0") → (serverB, "1.0.0") is what depends on
		// the second-column comparison.
		results, _, err := db.ListServers(ctx, nil, nil, serverA+":1.0.0", 100)
		require.NoError(t, err)
		got := filterTo(results)
		require.Len(t, got, 4, "expected 4 rows after cursor at A:1.0.0")
		assert.Equal(t, serverA, got[0].Server.Name)
		assert.Equal(t, "2.0.0", got[0].Server.Version)
		assert.Equal(t, serverA, got[1].Server.Name)
		assert.Equal(t, "3.0.0", got[1].Server.Version)
		assert.Equal(t, serverB, got[2].Server.Name)
		assert.Equal(t, "1.0.0", got[2].Server.Version)
		assert.Equal(t, serverB, got[3].Server.Name)
		assert.Equal(t, "2.0.0", got[3].Server.Version)

		// Cursor at the *last* version of serverA must cross the server boundary
		// and return serverB rows only.
		results, _, err = db.ListServers(ctx, nil, nil, serverA+":3.0.0", 100)
		require.NoError(t, err)
		got = filterTo(results)
		require.Len(t, got, 2, "expected 2 rows after cursor at A:3.0.0")
		assert.Equal(t, serverB, got[0].Server.Name)
		assert.Equal(t, "1.0.0", got[0].Server.Version)
		assert.Equal(t, serverB, got[1].Server.Name)
		assert.Equal(t, "2.0.0", got[1].Server.Version)

		// Page-by-page traversal with size=2 must produce the same global ordering
		// (A 1.0.0, A 2.0.0, A 3.0.0, B 1.0.0, B 2.0.0).
		var paged []*apiv0.ServerResponse
		cursor := ""
		for {
			rs, next, err := db.ListServers(ctx, nil,
				&database.ServerFilter{SubstringName: stringPtr("cursor-test-")},
				cursor, 2)
			require.NoError(t, err)
			paged = append(paged, rs...)
			if next == "" || len(rs) < 2 {
				break
			}
			cursor = next
		}
		require.Len(t, paged, 5)
		want := []struct{ name, version string }{
			{serverA, "1.0.0"}, {serverA, "2.0.0"}, {serverA, "3.0.0"},
			{serverB, "1.0.0"}, {serverB, "2.0.0"},
		}
		for i, w := range want {
			assert.Equal(t, w.name, paged[i].Server.Name, "row %d name", i)
			assert.Equal(t, w.version, paged[i].Server.Version, "row %d version", i)
		}
	})
}

func TestPostgreSQL_NewStatusFields(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	t.Run("status_changed_at field functionality", func(t *testing.T) {
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/status-changed-at-test",
			Description: "Test server for status_changed_at field",
			Version:     "1.0.0",
		}

		// Create server with specific status_changed_at
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Retrieve and verify status_changed_at
		result, err := db.GetServerByNameAndVersion(ctx, nil, serverJSON.Name, serverJSON.Version, false)
		require.NoError(t, err)
		assert.NotNil(t, result.Meta.Official)
		assert.Equal(t, timeNow.Unix(), result.Meta.Official.StatusChangedAt.Unix())
	})

	t.Run("status_message field functionality", func(t *testing.T) {
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/status-message-test",
			Description: "Test server for status_message field",
			Version:     "1.0.0",
		}

		statusMessage := "This server is deprecated due to security issues. Please migrate to v2.0.0"
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusDeprecated,
			StatusChangedAt: timeNow,
			StatusMessage:   &statusMessage,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Retrieve and verify status_message
		result, err := db.GetServerByNameAndVersion(ctx, nil, serverJSON.Name, serverJSON.Version, false)
		require.NoError(t, err)
		assert.NotNil(t, result.Meta.Official)
		assert.NotNil(t, result.Meta.Official.StatusMessage)
		assert.Equal(t, statusMessage, *result.Meta.Official.StatusMessage)
	})

	t.Run("deleted status functionality", func(t *testing.T) {
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/deleted-status-test",
			Description: "Test server for deleted status",
			Version:     "1.0.0",
		}

		statusMessage := "This version has critical security vulnerabilities and has been deleted"

		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusDeleted,
			StatusChangedAt: timeNow,
			StatusMessage:   &statusMessage,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        false, // Deleted versions should not be latest
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Retrieve and verify deleted status with all fields (need includeDeleted=true)
		result, err := db.GetServerByNameAndVersion(ctx, nil, serverJSON.Name, serverJSON.Version, true)
		require.NoError(t, err)
		assert.NotNil(t, result.Meta.Official)
		assert.Equal(t, model.StatusDeleted, result.Meta.Official.Status)
		assert.NotNil(t, result.Meta.Official.StatusMessage)
		assert.Equal(t, statusMessage, *result.Meta.Official.StatusMessage)
		assert.False(t, result.Meta.Official.IsLatest)
	})

	t.Run("nil status_message", func(t *testing.T) {
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/nil-fields-test",
			Description: "Test server for nil optional fields",
			Version:     "1.0.0",
		}

		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: timeNow,
			StatusMessage:   nil, // Explicitly nil
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)

		// Retrieve and verify nil fields are handled correctly
		result, err := db.GetServerByNameAndVersion(ctx, nil, serverJSON.Name, serverJSON.Version, false)
		require.NoError(t, err)
		assert.NotNil(t, result.Meta.Official)
		assert.Nil(t, result.Meta.Official.StatusMessage)
	})

	t.Run("status_changed_at constraint enforcement", func(t *testing.T) {
		serverJSON := &apiv0.ServerJSON{
			Name:        "com.example/constraint-test",
			Description: "Test server for constraint validation",
			Version:     "1.0.0",
		}

		// Try to create server with status_changed_at before published_at (should fail)
		earlierTime := timeNow.Add(-1 * time.Hour)
		officialMeta := &apiv0.RegistryExtensions{
			Status:          model.StatusActive,
			StatusChangedAt: earlierTime, // Before published_at
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		assert.Error(t, err)
		assert.Contains(t, err.Error(), "check_status_changed_at_after_published")
	})

	t.Run("all status transitions work", func(t *testing.T) {
		// Test that we can create servers with all valid status values
		statuses := []model.Status{
			model.StatusActive,
			model.StatusDeprecated,
			model.StatusDeleted,
		}

		for i, status := range statuses {
			serverJSON := &apiv0.ServerJSON{
				Name:        fmt.Sprintf("com.example/status-test-%d", i),
				Description: fmt.Sprintf("Test server for status %s", status),
				Version:     "1.0.0",
			}

			officialMeta := &apiv0.RegistryExtensions{
				Status:          status,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        true,
			}

			_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
			assert.NoError(t, err, "Should be able to create server with status: %s", status)

			// Verify the status was set correctly (use includeDeleted=true since we test all statuses including deleted)
			result, err := db.GetServerByNameAndVersion(ctx, nil, serverJSON.Name, serverJSON.Version, true)
			require.NoError(t, err)
			assert.Equal(t, status, result.Meta.Official.Status)
		}
	})
}

func TestPostgreSQL_StatusFieldsInListOperations(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Create test servers with different statuses and status fields
	testServers := []struct {
		name          string
		status        model.Status
		statusMessage *string
	}{
		{
			name:          "com.example/active-server",
			status:        model.StatusActive,
			statusMessage: nil,
		},
		{
			name:          "com.example/deprecated-server",
			status:        model.StatusDeprecated,
			statusMessage: stringPtr("Deprecated in favor of v2"),
		},
		{
			name:          "com.example/deleted-server",
			status:        model.StatusDeleted,
			statusMessage: stringPtr("Security vulnerability found"),
		},
	}

	// Create all test servers
	for _, server := range testServers {
		serverJSON := &apiv0.ServerJSON{
			Name:        server.name,
			Description: "Test server for list operations",
			Version:     "1.0.0",
		}

		officialMeta := &apiv0.RegistryExtensions{
			Status:          server.status,
			StatusChangedAt: timeNow,
			StatusMessage:   server.statusMessage,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	t.Run("ListServers includes new status fields", func(t *testing.T) {
		results, _, err := db.ListServers(ctx, nil, nil, "", 10)
		require.NoError(t, err)

		// Find our test servers in the results
		foundServers := make(map[string]*apiv0.ServerResponse)
		for _, result := range results {
			for _, testServer := range testServers {
				if result.Server.Name == testServer.name {
					foundServers[testServer.name] = result
				}
			}
		}

		// Verify all test servers were found with correct status fields
		for _, testServer := range testServers {
			result, found := foundServers[testServer.name]
			assert.True(t, found, "Server %s should be found in list results", testServer.name)
			if !found {
				continue
			}

			assert.NotNil(t, result.Meta.Official)
			assert.Equal(t, testServer.status, result.Meta.Official.Status)
			assert.Equal(t, timeNow.Unix(), result.Meta.Official.StatusChangedAt.Unix())

			if testServer.statusMessage != nil {
				assert.NotNil(t, result.Meta.Official.StatusMessage)
				assert.Equal(t, *testServer.statusMessage, *result.Meta.Official.StatusMessage)
			} else {
				assert.Nil(t, result.Meta.Official.StatusMessage)
			}
		}
	})

	t.Run("GetServerByName includes new status fields", func(t *testing.T) {
		for _, testServer := range testServers {
			// Use includeDeleted=true since testServers includes deleted status
			result, err := db.GetServerByName(ctx, nil, testServer.name, true)
			require.NoError(t, err)

			assert.NotNil(t, result.Meta.Official)
			assert.Equal(t, testServer.status, result.Meta.Official.Status)
			assert.Equal(t, timeNow.Unix(), result.Meta.Official.StatusChangedAt.Unix())

			if testServer.statusMessage != nil {
				assert.NotNil(t, result.Meta.Official.StatusMessage)
				assert.Equal(t, *testServer.statusMessage, *result.Meta.Official.StatusMessage)
			} else {
				assert.Nil(t, result.Meta.Official.StatusMessage)
			}
		}
	})
}

func TestPostgreSQL_SetAllVersionsStatus(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	t.Run("update all versions status successfully", func(t *testing.T) {
		serverName := "com.example/all-versions-status-test"
		versions := []string{"1.0.0", "1.1.0", "2.0.0"}

		// Create multiple versions
		for i, version := range versions {
			serverJSON := &apiv0.ServerJSON{
				Name:        serverName,
				Description: "Test server for all-versions status update",
				Version:     version,
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        i == len(versions)-1,
			}

			_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
			require.NoError(t, err)
		}

		// Update all versions to deprecated
		statusMessage := "All versions deprecated"

		results, err := db.SetAllVersionsStatus(ctx, nil, serverName, model.StatusDeprecated, &statusMessage)
		assert.NoError(t, err)
		assert.Len(t, results, 3)

		// Verify all versions were updated
		for _, result := range results {
			assert.Equal(t, model.StatusDeprecated, result.Meta.Official.Status)
			assert.NotNil(t, result.Meta.Official.StatusMessage)
			assert.Equal(t, statusMessage, *result.Meta.Official.StatusMessage)
		}

		// Verify by fetching each version individually
		for _, version := range versions {
			server, err := db.GetServerByNameAndVersion(ctx, nil, serverName, version, false)
			require.NoError(t, err)
			assert.Equal(t, model.StatusDeprecated, server.Meta.Official.Status)
			assert.NotNil(t, server.Meta.Official.StatusMessage)
			assert.Equal(t, statusMessage, *server.Meta.Official.StatusMessage)
		}
	})

	t.Run("update non-existent server returns error", func(t *testing.T) {
		results, err := db.SetAllVersionsStatus(ctx, nil, "com.example/non-existent-server", model.StatusDeprecated, nil)
		assert.Error(t, err)
		assert.ErrorIs(t, err, database.ErrNotFound)
		assert.Nil(t, results)
	})

	t.Run("update all versions to deleted", func(t *testing.T) {
		serverName := "com.example/all-versions-deleted-test"

		// Create multiple versions
		for i, version := range []string{"1.0.0", "1.1.0"} {
			serverJSON := &apiv0.ServerJSON{
				Name:        serverName,
				Description: "Test server for deleting",
				Version:     version,
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          model.StatusActive,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        i == 1,
			}

			_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
			require.NoError(t, err)
		}

		// Delete all versions
		statusMessage := "Critical security vulnerability"
		results, err := db.SetAllVersionsStatus(ctx, nil, serverName, model.StatusDeleted, &statusMessage)
		assert.NoError(t, err)
		assert.Len(t, results, 2)

		// Verify all versions are deleted
		for _, result := range results {
			assert.Equal(t, model.StatusDeleted, result.Meta.Official.Status)
			assert.NotNil(t, result.Meta.Official.StatusMessage)
			assert.Equal(t, statusMessage, *result.Meta.Official.StatusMessage)
		}
	})

	t.Run("transition from deleted back to active", func(t *testing.T) {
		serverName := "com.example/all-versions-reactivate-test"

		// Create server in deleted state
		for i, version := range []string{"1.0.0", "2.0.0"} {
			serverJSON := &apiv0.ServerJSON{
				Name:        serverName,
				Description: "Test server for reactivation",
				Version:     version,
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          model.StatusDeleted,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        i == 1,
			}

			_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
			require.NoError(t, err)
		}

		// Reactivate all versions
		results, err := db.SetAllVersionsStatus(ctx, nil, serverName, model.StatusActive, nil)
		assert.NoError(t, err)
		assert.Len(t, results, 2)

		// Verify all versions are active and metadata is cleared
		for _, result := range results {
			assert.Equal(t, model.StatusActive, result.Meta.Official.Status)
			assert.Nil(t, result.Meta.Official.StatusMessage)
		}
	})
}

func TestPostgreSQL_IncludeDeletedFilter(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()
	timeNow := time.Now()

	// Create test servers with different statuses
	testServers := []struct {
		name    string
		version string
		status  model.Status
	}{
		{
			name:    "com.example/deleted-filter-active",
			version: "1.0.0",
			status:  model.StatusActive,
		},
		{
			name:    "com.example/deleted-filter-deprecated",
			version: "1.0.0",
			status:  model.StatusDeprecated,
		},
		{
			name:    "com.example/deleted-filter-deleted",
			version: "1.0.0",
			status:  model.StatusDeleted,
		},
	}

	// Create all test servers
	for _, server := range testServers {
		serverJSON := &apiv0.ServerJSON{
			Name:        server.name,
			Description: "Test server for include deleted filter",
			Version:     server.version,
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          server.status,
			StatusChangedAt: timeNow,
			PublishedAt:     timeNow,
			UpdatedAt:       timeNow,
			IsLatest:        true,
		}

		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	t.Run("excludes deleted by default (nil IncludeDeleted)", func(t *testing.T) {
		filter := &database.ServerFilter{
			SubstringName: stringPtr("deleted-filter"),
		}

		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)

		// Should only get active and deprecated servers
		assert.Len(t, results, 2)

		for _, result := range results {
			assert.NotEqual(t, model.StatusDeleted, result.Meta.Official.Status,
				"Deleted servers should be excluded by default")
		}

		// Verify we got the expected servers
		names := make([]string, len(results))
		for i, r := range results {
			names[i] = r.Server.Name
		}
		assert.Contains(t, names, "com.example/deleted-filter-active")
		assert.Contains(t, names, "com.example/deleted-filter-deprecated")
	})

	t.Run("excludes deleted when IncludeDeleted is false", func(t *testing.T) {
		filter := &database.ServerFilter{
			SubstringName:  stringPtr("deleted-filter"),
			IncludeDeleted: boolPtr(false),
		}

		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)

		// Should only get active and deprecated servers
		assert.Len(t, results, 2)

		for _, result := range results {
			assert.NotEqual(t, model.StatusDeleted, result.Meta.Official.Status,
				"Deleted servers should be excluded when IncludeDeleted is false")
		}
	})

	t.Run("includes deleted when IncludeDeleted is true", func(t *testing.T) {
		filter := &database.ServerFilter{
			SubstringName:  stringPtr("deleted-filter"),
			IncludeDeleted: boolPtr(true),
		}

		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)

		// Should get all servers including deleted
		assert.Len(t, results, 3)

		// Verify we got all statuses
		statuses := make(map[model.Status]bool)
		for _, result := range results {
			statuses[result.Meta.Official.Status] = true
		}

		assert.True(t, statuses[model.StatusActive], "Should include active servers")
		assert.True(t, statuses[model.StatusDeprecated], "Should include deprecated servers")
		assert.True(t, statuses[model.StatusDeleted], "Should include deleted servers")
	})

	t.Run("combined filters with include deleted", func(t *testing.T) {
		// Test that IncludeDeleted works correctly with other filters
		filter := &database.ServerFilter{
			SubstringName:  stringPtr("deleted-filter"),
			Version:        stringPtr("1.0.0"),
			IsLatest:       boolPtr(true),
			IncludeDeleted: boolPtr(true),
		}

		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)

		// Should get all 3 servers (all match version and isLatest criteria)
		assert.Len(t, results, 3)
	})

	t.Run("multiple versions with deleted filtering", func(t *testing.T) {
		serverName := "com.example/multi-version-deleted-test"

		// Create server with multiple versions, one deleted
		versionsData := []struct {
			version string
			status  model.Status
		}{
			{"1.0.0", model.StatusDeleted}, // Old version, deleted
			{"1.1.0", model.StatusActive},  // Current stable
			{"2.0.0", model.StatusActive},  // Latest
		}

		for i, v := range versionsData {
			serverJSON := &apiv0.ServerJSON{
				Name:        serverName,
				Description: "Multi-version server",
				Version:     v.version,
			}
			officialMeta := &apiv0.RegistryExtensions{
				Status:          v.status,
				StatusChangedAt: timeNow,
				PublishedAt:     timeNow,
				UpdatedAt:       timeNow,
				IsLatest:        i == len(versionsData)-1,
			}

			_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
			require.NoError(t, err)
		}

		// Without IncludeDeleted - should get only active versions
		filter := &database.ServerFilter{
			Name:           stringPtr(serverName),
			IncludeDeleted: boolPtr(false),
		}
		results, _, err := db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)
		assert.Len(t, results, 2, "Should only get non-deleted versions")

		// With IncludeDeleted - should get all versions
		filter.IncludeDeleted = boolPtr(true)
		results, _, err = db.ListServers(ctx, nil, filter, "", 10)
		require.NoError(t, err)
		assert.Len(t, results, 3, "Should get all versions including deleted")
	})
}

// TestMigration014_HealIsLatest exercises migrations/014_heal_is_latest.sql against
// synthetic broken states by re-running its SQL after seeding rows directly. The migration
// itself ran via the template DB; since it's idempotent (only matches servers with no
// non-deleted is_latest row), re-running it here only acts on the rows we just broke.
func TestMigration014_HealIsLatest(t *testing.T) {
	db := database.NewTestDB(t)
	ctx := context.Background()

	migrationSQL, err := os.ReadFile("migrations/014_heal_is_latest.sql")
	require.NoError(t, err)

	createVersion := func(t *testing.T, name, version string, publishedAt time.Time, status model.Status, isLatest bool) {
		t.Helper()
		serverJSON := &apiv0.ServerJSON{
			Schema:      model.CurrentSchemaURL,
			Name:        name,
			Description: "test",
			Version:     version,
		}
		officialMeta := &apiv0.RegistryExtensions{
			Status:          status,
			StatusChangedAt: publishedAt,
			PublishedAt:     publishedAt,
			UpdatedAt:       publishedAt,
			IsLatest:        isLatest,
		}
		_, err := db.CreateServer(ctx, nil, serverJSON, officialMeta)
		require.NoError(t, err)
	}

	runHeal := func(t *testing.T) {
		t.Helper()
		err := db.InTransaction(ctx, func(ctx context.Context, tx pgx.Tx) error {
			_, err := tx.Exec(ctx, string(migrationSQL))
			return err
		})
		require.NoError(t, err)
	}

	versionState := func(t *testing.T, name, version string) (model.Status, bool) {
		t.Helper()
		v, err := db.GetServerByNameAndVersion(ctx, nil, name, version, true)
		require.NoError(t, err)
		return v.Meta.Official.Status, v.Meta.Official.IsLatest
	}

	t.Run("kubernetes-mcp-server scenario picks highest semver", func(t *testing.T) {
		name := "io.test/k8s-scenario"
		base := time.Now().Add(-10 * time.Hour)
		// 1.0.0 published first, then 0.0.50, 0.0.51, 0.0.59, 0.0.60, 0.0.61.
		// 1.0.0 was the original latest and got soft-deleted, leaving is_latest stranded.
		createVersion(t, name, "1.0.0", base, model.StatusDeleted, true)
		createVersion(t, name, "0.0.50", base.Add(1*time.Hour), model.StatusActive, false)
		createVersion(t, name, "0.0.51", base.Add(2*time.Hour), model.StatusActive, false)
		createVersion(t, name, "0.0.59", base.Add(3*time.Hour), model.StatusActive, false)
		createVersion(t, name, "0.0.60", base.Add(4*time.Hour), model.StatusActive, false)
		createVersion(t, name, "0.0.61", base.Add(5*time.Hour), model.StatusActive, false)

		runHeal(t)

		_, isLatest := versionState(t, name, "1.0.0")
		assert.False(t, isLatest, "deleted 1.0.0 should no longer be latest")
		_, isLatest = versionState(t, name, "0.0.61")
		assert.True(t, isLatest, "highest active version should become latest")
		for _, v := range []string{"0.0.50", "0.0.51", "0.0.59", "0.0.60"} {
			_, isLatest := versionState(t, name, v)
			assert.False(t, isLatest, "version %s should not be latest", v)
		}
	})

	t.Run("backport scenario picks highest semver not most recent", func(t *testing.T) {
		// Published 2.0.0 (deleted), then 1.0.1 hotfix, then 1.0.0 (older patch backported later).
		// Most-recent-published would pick 1.0.0; semver-aware picks 1.0.1.
		name := "io.test/backport-scenario"
		base := time.Now().Add(-10 * time.Hour)
		createVersion(t, name, "2.0.0", base, model.StatusDeleted, true)
		createVersion(t, name, "1.0.1", base.Add(1*time.Hour), model.StatusActive, false)
		createVersion(t, name, "1.0.0", base.Add(2*time.Hour), model.StatusActive, false)

		runHeal(t)

		_, isLatest := versionState(t, name, "1.0.1")
		assert.True(t, isLatest, "1.0.1 should win on semver despite 1.0.0 being published more recently")
		_, isLatest = versionState(t, name, "1.0.0")
		assert.False(t, isLatest)
	})

	t.Run("no is_latest row at all gets healed", func(t *testing.T) {
		// Defensive case: nothing flagged latest, but active versions exist.
		name := "io.test/no-latest-flag"
		base := time.Now().Add(-10 * time.Hour)
		createVersion(t, name, "1.0.0", base, model.StatusActive, false)
		createVersion(t, name, "1.1.0", base.Add(1*time.Hour), model.StatusActive, false)

		runHeal(t)

		_, isLatest := versionState(t, name, "1.1.0")
		assert.True(t, isLatest)
		_, isLatest = versionState(t, name, "1.0.0")
		assert.False(t, isLatest)
	})

	t.Run("all-deleted server is left untouched", func(t *testing.T) {
		// No non-deleted version → nothing to promote, leave existing flags alone so the
		// server remains addressable via includeDeleted=true admin lookups.
		name := "io.test/all-deleted"
		base := time.Now().Add(-10 * time.Hour)
		createVersion(t, name, "1.0.0", base, model.StatusDeleted, true)
		createVersion(t, name, "2.0.0", base.Add(1*time.Hour), model.StatusDeleted, false)

		runHeal(t)

		_, isLatest := versionState(t, name, "1.0.0")
		assert.True(t, isLatest, "all-deleted server should keep its existing latest flag")
		_, isLatest = versionState(t, name, "2.0.0")
		assert.False(t, isLatest)
	})

	t.Run("healthy server is left untouched", func(t *testing.T) {
		name := "io.test/healthy"
		base := time.Now().Add(-10 * time.Hour)
		createVersion(t, name, "1.0.0", base, model.StatusActive, false)
		createVersion(t, name, "2.0.0", base.Add(1*time.Hour), model.StatusActive, true)

		runHeal(t)

		_, isLatest := versionState(t, name, "2.0.0")
		assert.True(t, isLatest)
		_, isLatest = versionState(t, name, "1.0.0")
		assert.False(t, isLatest)
	})

	t.Run("non-semver versions fall back to published_at", func(t *testing.T) {
		name := "io.test/non-semver"
		base := time.Now().Add(-10 * time.Hour)
		createVersion(t, name, "rolling", base, model.StatusDeleted, true)
		createVersion(t, name, "build-100", base.Add(1*time.Hour), model.StatusActive, false)
		createVersion(t, name, "build-200", base.Add(2*time.Hour), model.StatusActive, false)

		runHeal(t)

		_, isLatest := versionState(t, name, "build-200")
		assert.True(t, isLatest, "without semver, most recently published wins")
	})
}

// Helper functions for creating pointers to basic types
func stringPtr(s string) *string {
	return &s
}

func boolPtr(b bool) *bool {
	return &b
}

func timePtr(t time.Time) *time.Time {
	return &t
}
