package db

import (
	"testing"

	"github.com/tidbcloud/aisupport/services/oncall/models"

	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
)

// TestBackfillEngineerTeamRoles covers the one-way migration from the legacy
// is_manager boolean to the role ladder, including the case that makes it safe
// to re-run: a manager demoted after the first backfill must stay demoted.
func TestBackfillEngineerTeamRoles(t *testing.T) {
	var err error
	DB, err = gorm.Open(sqlite.Open("file:backfill_test?mode=memory&cache=shared"), &gorm.Config{})
	if err != nil {
		t.Fatalf("connect: %v", err)
	}
	if err := DB.AutoMigrate(&models.EngineerTeam{}); err != nil {
		t.Fatalf("migrate: %v", err)
	}

	// Rows as they look right after the column is added: role unset, is_manager
	// still carrying the truth.
	rows := []struct {
		engineerID uint
		isManager  bool
	}{
		{1, true},
		{2, false},
	}
	for _, r := range rows {
		if err := DB.Exec("INSERT INTO engineer_teams (engineer_id, team_id, role, is_manager) VALUES (?, ?, '', ?)",
			r.engineerID, 1, r.isManager).Error; err != nil {
			t.Fatalf("insert engineer %d: %v", r.engineerID, err)
		}
	}

	if err := backfillEngineerTeamRoles(); err != nil {
		t.Fatalf("backfill: %v", err)
	}
	assertRole := func(engineerID uint, want string) {
		t.Helper()
		var link models.EngineerTeam
		if err := DB.Where("engineer_id = ?", engineerID).First(&link).Error; err != nil {
			t.Fatalf("load engineer %d: %v", engineerID, err)
		}
		if link.Role != want {
			t.Fatalf("engineer %d role = %q, want %q", engineerID, link.Role, want)
		}
	}
	assertRole(1, models.TeamRoleManager)
	assertRole(2, models.TeamRoleMember)

	// A demotion through the service keeps both columns in step, so re-running
	// the backfill (every process start) must not resurrect the old role.
	if err := DB.Model(&models.EngineerTeam{}).Where("engineer_id = ?", 1).
		Updates(map[string]interface{}{"role": models.TeamRoleEditor, "is_manager": false}).Error; err != nil {
		t.Fatalf("demote: %v", err)
	}
	if err := backfillEngineerTeamRoles(); err != nil {
		t.Fatalf("second backfill: %v", err)
	}
	assertRole(1, models.TeamRoleEditor)
}
