package persistence

import (
	"database/sql"
	"reflect"
	"testing"

	database "github.com/nexuscrm/db"
)

func TestPermissionStateDirectProjectionBatchesStayBounded(t *testing.T) {
	var sizes []int
	err := forEachPermissionStateDirectProjectionBatch(make([]int, 401), func(batch []int) error {
		sizes = append(sizes, len(batch))
		return nil
	})
	if err != nil || !reflect.DeepEqual(sizes, []int{200, 200, 1}) {
		t.Fatalf("projection batches = %v, error = %v", sizes, err)
	}
}

func newPermissionStateDirectWriterRepository(
	t *testing.T,
	db *sql.DB,
) (*PermissionRepository, *PermissionStateDirectWriterCoordinator) {
	t.Helper()
	transactions := NewTransactionManager(database.NewConnectionFromDB(db))
	authority := newPermissionStateAuthorityForTest(t, transactions)
	coordinator, err := NewPermissionStateDirectWriterCoordinator(transactions, authority)
	if err != nil {
		t.Fatal(err)
	}
	repository := NewPermissionRepository(db)
	if err := repository.SetPermissionStateDirectWriterCoordinator(coordinator); err != nil {
		t.Fatal(err)
	}
	return repository, coordinator
}

func newPermissionStateMetadataDirectWriterRepository(
	t *testing.T,
	db *sql.DB,
) (*MetadataRepository, *PermissionStateDirectWriterCoordinator) {
	t.Helper()
	transactions := NewTransactionManager(database.NewConnectionFromDB(db))
	authority := newPermissionStateAuthorityForTest(t, transactions)
	coordinator, err := NewPermissionStateDirectWriterCoordinator(transactions, authority)
	if err != nil {
		t.Fatal(err)
	}
	repository := NewMetadataRepository(db)
	if err := repository.SetPermissionStateDirectWriterCoordinator(coordinator); err != nil {
		t.Fatal(err)
	}
	return repository, coordinator
}

func newPermissionStateSchemaDirectWriterRepository(
	t *testing.T,
	db *sql.DB,
) (*SchemaRepository, *PermissionStateDirectWriterCoordinator) {
	t.Helper()
	transactions := NewTransactionManager(database.NewConnectionFromDB(db))
	authority := newPermissionStateAuthorityForTest(t, transactions)
	coordinator, err := NewPermissionStateDirectWriterCoordinator(transactions, authority)
	if err != nil {
		t.Fatal(err)
	}
	repository := NewSchemaRepository(db, nil)
	if err := repository.SetPermissionStateDirectWriterCoordinator(coordinator); err != nil {
		t.Fatal(err)
	}
	return repository, coordinator
}
