package tenantmanager

import (
	"errors"
	"testing"

	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/cql/cqlerrors"
	"github.com/everything-on-mysql/cassandra-on-mysql/pkg/mysqlbackend"
)

func TestLeaseMySQLSlotEnforcesLimit(t *testing.T) {
	tenant := &TenantContext{mysqlLimiter: newLimiter(1)}

	release, err := tenant.LeaseMySQLSlot()
	if err != nil {
		t.Fatalf("LeaseMySQLSlot failed: %v", err)
	}

	if _, err := tenant.LeaseMySQLSlot(); !errors.Is(err, ErrMySQLLimitExceeded) {
		t.Fatalf("expected ErrMySQLLimitExceeded, got %v", err)
	}

	release()
	release()

	if _, err := tenant.LeaseMySQLSlot(); err != nil {
		t.Fatalf("expected slot after release, got %v", err)
	}
}

func TestAcquireConnLeaseReturnsOverloadedWhenLimitReached(t *testing.T) {
	tenant := &TenantContext{mysqlLimiter: newLimiter(1)}

	release, err := tenant.AcquireConnLease(mysqlbackend.ConnLeaseKindBulk)
	if err != nil {
		t.Fatalf("first bulk conn lease failed: %v", err)
	}
	if release == nil {
		t.Fatal("expected release func")
	}

	_, err = tenant.AcquireConnLease(mysqlbackend.ConnLeaseKindBulk)
	if err == nil {
		t.Fatal("expected second bulk conn lease to fail")
	}
	var coded interface{ Code() int }
	if !errors.As(err, &coded) || coded.Code() != cqlerrors.CodeOverloaded {
		t.Fatalf("expected overloaded error, got %v", err)
	}

	release()

	if _, err := tenant.AcquireConnLease(mysqlbackend.ConnLeaseKindStandard); err != nil {
		t.Fatalf("expected standard conn lease after release, got %v", err)
	}
}
