package router

import (
	"context"
	"testing"
	"time"
)

func TestMemoryDirectorySameOwnerRenewalPreservesLeaseToken(t *testing.T) {
	ctx := context.Background()
	directory := NewMemoryDirectory()
	now := time.Unix(100, 0).UTC()

	first, err := directory.EnsureOwner(ctx, "room-1", "node-a", now, 10*time.Second)
	if err != nil {
		t.Fatalf("first EnsureOwner failed: %v", err)
	}

	renewed, err := directory.EnsureOwner(ctx, "room-1", "node-a", now.Add(time.Second), 10*time.Second)
	if err != nil {
		t.Fatalf("renew EnsureOwner failed: %v", err)
	}
	if renewed.LeaseToken != first.LeaseToken {
		// 同节点续租不能换 token，否则 Room Cell 命令进入 mailbox 后会被后台续租误伤。
		t.Fatalf("same owner renewal rotated token: first=%s renewed=%s", first.LeaseToken, renewed.LeaseToken)
	}
	if !renewed.ExpiresAt.After(first.ExpiresAt) {
		t.Fatalf("same owner renewal did not extend expiry: first=%s renewed=%s", first.ExpiresAt, renewed.ExpiresAt)
	}

	ok, err := directory.VerifyOwner(ctx, "room-1", "node-a", first.LeaseToken, now.Add(2*time.Second))
	if err != nil {
		t.Fatalf("VerifyOwner failed: %v", err)
	}
	if !ok {
		t.Fatal("original token should remain valid after same owner renewal")
	}
}

func TestMemoryDirectoryExpiredLeaseCreatesNewToken(t *testing.T) {
	ctx := context.Background()
	directory := NewMemoryDirectory()
	now := time.Unix(100, 0).UTC()

	first, err := directory.EnsureOwner(ctx, "room-1", "node-a", now, time.Second)
	if err != nil {
		t.Fatalf("first EnsureOwner failed: %v", err)
	}

	taken, err := directory.EnsureOwner(ctx, "room-1", "node-b", now.Add(2*time.Second), 10*time.Second)
	if err != nil {
		t.Fatalf("takeover EnsureOwner failed: %v", err)
	}
	if taken.NodeID != "node-b" {
		t.Fatalf("expired lease should be taken by node-b, got %+v", taken)
	}
	if taken.LeaseToken == first.LeaseToken {
		// 过期接管代表新的执行权实例，必须换 token 来挡住旧 owner 的迟到提交。
		t.Fatal("expired lease takeover must create a new token")
	}
}
