package connector_workqueue

import (
	"testing"
	"time"
)

func TestLaneMaintenancePreservesTargetOverrideAndProcessingGuardsTiDB(t *testing.T) {
	db, cleanup := openWorkqueueTiDB(t)
	defer cleanup()
	createWorkqueueClaimTables(t, db)
	now := time.Now().UTC().Truncate(time.Microsecond)
	for _, row := range []struct {
		id, state      string
		source, target any
		ordinal        int64
	}{
		{"head", WorkStateBlocked, "lane", nil, 1},
		{"source-tail", WorkStatePending, "lane", "", 2},
		{"target-tail", WorkStateRetry, "other", "lane", 3},
		{"overridden", WorkStatePending, "lane", "different", 0},
		{"foreign-generation", WorkStatePending, "other", "lane", 0},
		{"foreign-pack", WorkStatePending, "lane", "", 0},
		{"future", WorkStatePending, "lane", nil, 0},
		{"inactive", WorkStateBlocked, "lane", nil, 0},
	} {
		insertWorkItemForLaneTest(t, db, row.id, row.state, row.source, row.target, row.ordinal, now)
	}
	for _, query := range []string{
		`UPDATE _System_ConnectorWorkItem SET Generation=8 WHERE WorkId='foreign-generation'`,
		`UPDATE _System_ConnectorWorkItem SET InstalledPackId='pack-2' WHERE WorkId='foreign-pack'`,
		`UPDATE _System_ConnectorWorkItem SET RunAfter=DATE_ADD(RunAfter, INTERVAL 1 HOUR) WHERE WorkId='future'`,
		`UPDATE _System_ConnectorWorkItem SET ProjectionKey='projection', ProjectionActiveKey=NULL WHERE WorkId='inactive'`,
	} {
		if _, err := db.Exec(query); err != nil {
			t.Fatal(err)
		}
	}
	repo := NewRepository(db, nil, nil)
	in := CreateWorkItemInput{InstalledPackID: "pack-1", Generation: 7, SourceLaneKey: "lane", Now: now}
	if err := repo.reconcileLaneReadyState(t.Context(), in); err != nil {
		t.Fatal(err)
	}
	for id, want := range map[string]string{"head": WorkStatePending, "source-tail": WorkStateBlocked, "target-tail": WorkStateBlockedRetry, "overridden": WorkStatePending, "foreign-generation": WorkStatePending, "foreign-pack": WorkStatePending, "future": WorkStatePending, "inactive": WorkStateBlocked} {
		var state string
		if err := db.QueryRow("SELECT State FROM _System_ConnectorWorkItem WHERE WorkId=?", id).Scan(&state); err != nil {
			t.Fatal(err)
		}
		if state != want {
			t.Errorf("%s=%s want %s", id, state, want)
		}
	}
	for _, target := range []any{nil, "", "lane"} {
		if _, err := db.Exec("UPDATE _System_ConnectorWorkItem SET State='blocked' WHERE WorkId='head'"); err != nil {
			t.Fatal(err)
		}
		if _, err := db.Exec("UPDATE _System_ConnectorWorkItem SET State='processing',SourceLaneKey='lane',TargetMutationLaneKey=? WHERE WorkId='source-tail'", target); err != nil {
			t.Fatal(err)
		}
		if err := repo.promoteLaneReadyHead(t.Context(), in, "lane", "head", now); err != nil {
			t.Fatal(err)
		}
		var state string
		if err := db.QueryRow("SELECT State FROM _System_ConnectorWorkItem WHERE WorkId='head'").Scan(&state); err != nil {
			t.Fatal(err)
		}
		if state != WorkStateBlocked {
			t.Fatalf("processing target=%v did not block promotion", target)
		}
	}
}
