package main

import (
	"database/sql"
	"strings"
	"testing"

	_ "github.com/ncruces/go-sqlite3/driver"
	_ "github.com/ncruces/go-sqlite3/embed"
)

var initGroups = []Group{
	{Id: "admin", Title: "Admin", Description: "Admin group"},
	{Id: "all", Title: "All", Description: "All members"},
}

// Helper function to create a new in-memory SQLite store for testing
func createTestStore(t *testing.T) Store {
	db, err := sql.Open("sqlite3", ":memory:")
	if err != nil {
		t.Fatal(err)
	}
	store, err := NewSQLiteStore(db)
	if err != nil {
		t.Fatal(err)
	}
	return store
}

// Helper function to create a store with initialized data
func createInitializedStore(t *testing.T) Store {
	store := createTestStore(t)
	adminUser := User{Id: "1", Username: "admin", Email: "admin@admin.com"}
	if err := store.Init(adminUser, initGroups); err != nil {
		t.Fatal(err)
	}
	return store
}

func TestNewSQLiteStore(t *testing.T) {
	db, err := sql.Open("sqlite3", ":memory:")
	if err != nil {
		t.Fatal(err)
	}
	defer db.Close()

	store, err := NewSQLiteStore(db)
	if err != nil {
		t.Fatal(err)
	}
	if store == nil {
		t.Fatal("expected store to be non-nil")
	}
}

func TestInit(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		adminUser := User{Id: "1", Username: "admin", Email: "admin@admin.com"}
		err := store.Init(adminUser, initGroups)
		if err != nil {
			t.Fatal(err)
		}

		// Verify user was created
		user, err := store.GetUser(nil, "1")
		if err != nil {
			t.Fatal(err)
		}
		if user.Username != "admin" || user.Email != "admin@admin.com" {
			t.Fatalf("unexpected user: %+v", user)
		}

		// Verify groups were created
		allGroups, err := store.GetAllGroups(nil)
		if err != nil {
			t.Fatal(err)
		}
		if len(allGroups) != 2 {
			t.Fatalf("expected 2 groups, got %d", len(allGroups))
		}

		// Verify user is member of both groups
		memberGroups, err := store.GetGroupsUserIsMemberOf(nil, "1")
		if err != nil {
			t.Fatal(err)
		}
		if len(memberGroups) != 2 {
			t.Fatalf("expected user to be member of 2 groups, got %d", len(memberGroups))
		}
	})

	t.Run("already_initialized", func(t *testing.T) {
		store := createInitializedStore(t)
		user2 := User{Id: "2", Username: "user2", Email: "user2@test.com"}
		err := store.Init(user2, []Group{})
		if err == nil || !strings.Contains(err.Error(), "already initialised") {
			t.Fatalf("expected 'already initialised' error, got: %v", err)
		}
	})
}

func TestCreateUser(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
		err := store.CreateUser(nil, user)
		if err != nil {
			t.Fatal(err)
		}

		retrievedUser, err := store.GetUser(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if retrievedUser.Id != "user1" || retrievedUser.Username != "testuser" || retrievedUser.Email != "test@test.com" {
			t.Fatalf("unexpected user: %+v", retrievedUser)
		}
	})

	t.Run("with_transaction", func(t *testing.T) {
		store := createTestStore(t)
		db := store.(*SQLiteStore).db
		tx, err := db.Begin()
		if err != nil {
			t.Fatal(err)
		}
		defer tx.Rollback()

		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
		err = store.CreateUser(tx, user)
		if err != nil {
			t.Fatal(err)
		}

		if err := tx.Commit(); err != nil {
			t.Fatal(err)
		}

		retrievedUser, err := store.GetUser(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if retrievedUser.Username != "testuser" {
			t.Fatalf("unexpected username: %s", retrievedUser.Username)
		}
	})

	t.Run("duplicate_id", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "testuser1", Email: "test1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		user2 := User{Id: "user1", Username: "testuser2", Email: "test2@test.com"}
		err = store.CreateUser(nil, user2)
		if err == nil {
			t.Fatal("expected error for duplicate user ID")
		}
	})

	t.Run("duplicate_username", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "testuser", Email: "test1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		user2 := User{Id: "user2", Username: "testuser", Email: "test2@test.com"}
		err = store.CreateUser(nil, user2)
		if err == nil {
			t.Fatal("expected error for duplicate username")
		}
	})

	t.Run("duplicate_email", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "testuser1", Email: "test@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		user2 := User{Id: "user2", Username: "testuser2", Email: "test@test.com"}
		err = store.CreateUser(nil, user2)
		if err == nil {
			t.Fatal("expected error for duplicate email")
		}
	})
}

func TestGetUser(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
		err := store.CreateUser(nil, user)
		if err != nil {
			t.Fatal(err)
		}

		retrievedUser, err := store.GetUser(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if retrievedUser.Id != "user1" || retrievedUser.Username != "testuser" || retrievedUser.Email != "test@test.com" {
			t.Fatalf("unexpected user: %+v", retrievedUser)
		}
	})

	t.Run("not_found", func(t *testing.T) {
		store := createTestStore(t)
		_, err := store.GetUser(nil, "nonexistent")
		if err == nil {
			t.Fatal("expected error for nonexistent user")
		}
	})
}

func TestGetAllUsers(t *testing.T) {
	store := createTestStore(t)

	// Create test users
	users := []User{
		{Id: "user1", Username: "testuser1", Email: "test1@test.com"},
		{Id: "user2", Username: "testuser2", Email: "test2@test.com"},
		{Id: "user3", Username: "testuser3", Email: "test3@test.com"},
	}

	for _, u := range users {
		err := store.CreateUser(nil, u)
		if err != nil {
			t.Fatal(err)
		}
	}

	allUsers, err := store.GetAllUsers(nil)
	if err != nil {
		t.Fatal(err)
	}
	if len(allUsers) != 3 {
		t.Fatalf("expected 3 users, got %d", len(allUsers))
	}
}

func TestGetUsers(t *testing.T) {
	store := createTestStore(t)

	// Create test users
	users := []User{
		{Id: "user1", Username: "testuser1", Email: "test1@test.com"},
		{Id: "user2", Username: "testuser2", Email: "test2@test.com"},
		{Id: "user3", Username: "testuser3", Email: "test3@test.com"},
	}

	for _, u := range users {
		err := store.CreateUser(nil, u)
		if err != nil {
			t.Fatal(err)
		}
	}

	selectedUsers, err := store.GetUsers(nil, []string{"user1", "user3"})
	if err != nil {
		t.Fatal(err)
	}
	if len(selectedUsers) != 2 {
		t.Fatalf("expected 2 users, got %d", len(selectedUsers))
	}

	userIds := make(map[string]bool)
	for _, u := range selectedUsers {
		userIds[u.Id] = true
	}
	if !userIds["user1"] || !userIds["user3"] {
		t.Fatal("unexpected users returned")
	}
}

func TestCreateGroup(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		owner := User{Id: "owner1", Username: "owner", Email: "owner@test.com"}
		err := store.CreateUser(nil, owner)
		if err != nil {
			t.Fatal(err)
		}

		group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
		err = store.CreateGroup(nil, "owner1", group)
		if err != nil {
			t.Fatal(err)
		}

		retrievedGroup, err := store.GetGroup(nil, "testgroup")
		if err != nil {
			t.Fatal(err)
		}
		if retrievedGroup.Id != group.Id || retrievedGroup.Title != group.Title {
			t.Fatalf("unexpected group: %+v", retrievedGroup)
		}

		// Verify owner was added
		owners, err := store.GetOwnerUsers(nil, "testgroup")
		if err != nil {
			t.Fatal(err)
		}
		if len(owners) != 1 || owners[0].Id != "owner1" {
			t.Fatalf("expected owner1 to be group owner, got: %+v", owners)
		}
	})

	t.Run("duplicate_id", func(t *testing.T) {
		store := createTestStore(t)
		owner := User{Id: "owner1", Username: "owner", Email: "owner@test.com"}
		err := store.CreateUser(nil, owner)
		if err != nil {
			t.Fatal(err)
		}

		group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
		err = store.CreateGroup(nil, "owner1", group)
		if err != nil {
			t.Fatal(err)
		}

		err = store.CreateGroup(nil, "owner1", group)
		if err == nil || !strings.Contains(err.Error(), "already exists") {
			t.Fatalf("expected 'already exists' error, got: %v", err)
		}
	})
}

func TestGetGroup(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createInitializedStore(t)
		group, err := store.GetGroup(nil, "admin")
		if err != nil {
			t.Fatal(err)
		}
		if group.Id != "admin" || group.Title != "Admin" {
			t.Fatalf("unexpected group: %+v", group)
		}
	})

	t.Run("not_found", func(t *testing.T) {
		store := createTestStore(t)
		_, err := store.GetGroup(nil, "nonexistent")
		if err == nil {
			t.Fatal("expected error for nonexistent group")
		}
	})
}

func TestGetAllGroups(t *testing.T) {
	store := createInitializedStore(t)
	groups, err := store.GetAllGroups(nil)
	if err != nil {
		t.Fatal(err)
	}
	if len(groups) != 2 {
		t.Fatalf("expected 2 groups, got %d", len(groups))
	}
}

func TestAddMemberUser(t *testing.T) {
	store := createTestStore(t)

	// Create users and group
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err := store.CreateUser(nil, user1)
	if err != nil {
		t.Fatal(err)
	}
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err = store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
	err = store.CreateGroup(nil, "owner1", group)
	if err != nil {
		t.Fatal(err)
	}

	err = store.AddMemberUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	members, err := store.GetMemberUsers(nil, "testgroup")
	if err != nil {
		t.Fatal(err)
	}
	if len(members) != 1 || members[0].Id != "user1" {
		t.Fatalf("expected user1 to be member, got: %+v", members)
	}
}

func TestAddOwnerUser(t *testing.T) {
	store := createTestStore(t)

	// Create users and group
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err := store.CreateUser(nil, user1)
	if err != nil {
		t.Fatal(err)
	}
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err = store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
	err = store.CreateGroup(nil, "owner1", group)
	if err != nil {
		t.Fatal(err)
	}

	err = store.AddOwnerUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	owners, err := store.GetOwnerUsers(nil, "testgroup")
	if err != nil {
		t.Fatal(err)
	}

	// Should have 2 owners now (original owner1 + user1)
	if len(owners) != 2 {
		t.Fatalf("expected 2 owners, got %d", len(owners))
	}

	ownerIds := make(map[string]bool)
	for _, owner := range owners {
		ownerIds[owner.Id] = true
	}
	if !ownerIds["owner1"] || !ownerIds["user1"] {
		t.Fatal("expected both owner1 and user1 to be owners")
	}
}

func TestAddMemberGroup(t *testing.T) {
	store := createTestStore(t)

	// Create owner and groups
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err := store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
	err = store.CreateGroup(nil, "owner1", parentGroup)
	if err != nil {
		t.Fatal(err)
	}
	childGroup := Group{Id: "child", Title: "Child Group", Description: "Child group"}
	err = store.CreateGroup(nil, "owner1", childGroup)
	if err != nil {
		t.Fatal(err)
	}

	err = store.AddMemberGroup(nil, "parent", "child")
	if err != nil {
		t.Fatal(err)
	}

	memberGroups, err := store.GetMemberGroups(nil, "parent")
	if err != nil {
		t.Fatal(err)
	}
	if len(memberGroups) != 1 || memberGroups[0].Id != "child" {
		t.Fatalf("expected child to be member group, got: %+v", memberGroups)
	}
}

func TestAddOwnerGroup(t *testing.T) {
	store := createTestStore(t)

	// Create owner and groups
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err := store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
	err = store.CreateGroup(nil, "owner1", parentGroup)
	if err != nil {
		t.Fatal(err)
	}
	ownerGroup := Group{Id: "ownergroup", Title: "Owner Group", Description: "Owner group"}
	err = store.CreateGroup(nil, "owner1", ownerGroup)
	if err != nil {
		t.Fatal(err)
	}

	err = store.AddOwnerGroup(nil, "parent", "ownergroup")
	if err != nil {
		t.Fatal(err)
	}

	ownerGroups, err := store.GetOwnerGroups(nil, "parent")
	if err != nil {
		t.Fatal(err)
	}
	if len(ownerGroups) != 1 || ownerGroups[0].Id != "ownergroup" {
		t.Fatalf("expected ownergroup to be owner group, got: %+v", ownerGroups)
	}
}

func TestRemoveMemberUser(t *testing.T) {
	store := createTestStore(t)

	// Setup: create user, owner, and group, then add user as member
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err := store.CreateUser(nil, user1)
	if err != nil {
		t.Fatal(err)
	}
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err = store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
	err = store.CreateGroup(nil, "owner1", group)
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddMemberUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	// Test removal
	err = store.RemoveMemberUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	members, err := store.GetMemberUsers(nil, "testgroup")
	if err != nil {
		t.Fatal(err)
	}
	if len(members) != 0 {
		t.Fatalf("expected no members after removal, got: %+v", members)
	}
}

func TestRemoveOwnerUser(t *testing.T) {
	store := createTestStore(t)

	// Setup: create users, group, and add second user as owner
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err := store.CreateUser(nil, user1)
	if err != nil {
		t.Fatal(err)
	}
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err = store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
	err = store.CreateGroup(nil, "owner1", group)
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddOwnerUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	// Test removal
	err = store.RemoveOwnerUser(nil, "testgroup", "user1")
	if err != nil {
		t.Fatal(err)
	}

	owners, err := store.GetOwnerUsers(nil, "testgroup")
	if err != nil {
		t.Fatal(err)
	}
	if len(owners) != 1 || owners[0].Id != "owner1" {
		t.Fatalf("expected only owner1 to remain, got: %+v", owners)
	}
}

func TestRemoveMemberGroup(t *testing.T) {
	store := createTestStore(t)

	// Setup: create groups and add one as member of the other
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err := store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
	err = store.CreateGroup(nil, "owner1", parentGroup)
	if err != nil {
		t.Fatal(err)
	}
	childGroup := Group{Id: "child", Title: "Child Group", Description: "Child group"}
	err = store.CreateGroup(nil, "owner1", childGroup)
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddMemberGroup(nil, "parent", "child")
	if err != nil {
		t.Fatal(err)
	}

	// Test removal
	err = store.RemoveMemberGroup(nil, "parent", "child")
	if err != nil {
		t.Fatal(err)
	}

	memberGroups, err := store.GetMemberGroups(nil, "parent")
	if err != nil {
		t.Fatal(err)
	}
	if len(memberGroups) != 0 {
		t.Fatalf("expected no member groups after removal, got: %+v", memberGroups)
	}
}

func TestRemoveOwnerGroup(t *testing.T) {
	store := createTestStore(t)

	// Setup: create groups and add one as owner of the other
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err := store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}
	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
	err = store.CreateGroup(nil, "owner1", parentGroup)
	if err != nil {
		t.Fatal(err)
	}
	ownerGroup := Group{Id: "ownergroup", Title: "Owner Group", Description: "Owner group"}
	err = store.CreateGroup(nil, "owner1", ownerGroup)
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddOwnerGroup(nil, "parent", "ownergroup")
	if err != nil {
		t.Fatal(err)
	}

	// Test removal
	err = store.RemoveOwnerGroup(nil, "parent", "ownergroup")
	if err != nil {
		t.Fatal(err)
	}

	ownerGroups, err := store.GetOwnerGroups(nil, "parent")
	if err != nil {
		t.Fatal(err)
	}
	if len(ownerGroups) != 0 {
		t.Fatalf("expected no owner groups after removal, got: %+v", ownerGroups)
	}
}

func TestGetGroupsUserOwns(t *testing.T) {
	store := createInitializedStore(t)
	groups, err := store.GetGroupsUserOwns(nil, "1")
	if err != nil {
		t.Fatal(err)
	}
	if len(groups) != 2 {
		t.Fatalf("expected 2 groups owned by user 1, got %d", len(groups))
	}
}

func TestGetGroupsUserIsMemberOf(t *testing.T) {
	store := createInitializedStore(t)
	groups, err := store.GetGroupsUserIsMemberOf(nil, "1")
	if err != nil {
		t.Fatal(err)
	}
	if len(groups) != 2 {
		t.Fatalf("expected user 1 to be member of 2 groups, got %d", len(groups))
	}
}

func TestGetGroupsUserCanActAs(t *testing.T) {
	store := createTestStore(t)

	// Create complex hierarchy: user1 -> groupA -> groupB -> groupC
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err := store.CreateUser(nil, user1)
	if err != nil {
		t.Fatal(err)
	}
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err = store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}

	groups := []Group{
		{Id: "groupA", Title: "Group A", Description: "Group A"},
		{Id: "groupB", Title: "Group B", Description: "Group B"},
		{Id: "groupC", Title: "Group C", Description: "Group C"},
	}

	for _, g := range groups {
		err = store.CreateGroup(nil, "owner1", g)
		if err != nil {
			t.Fatal(err)
		}
	}

	// Build hierarchy: user1 member of groupA, groupA member of groupB, groupB member of groupC
	err = store.AddMemberUser(nil, "groupA", "user1")
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddMemberGroup(nil, "groupB", "groupA")
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddMemberGroup(nil, "groupC", "groupB")
	if err != nil {
		t.Fatal(err)
	}

	// user1 should be able to act as groupA, groupB, and groupC
	canActAs, err := store.GetGroupsUserCanActAs(nil, "user1")
	if err != nil {
		t.Fatal(err)
	}

	if len(canActAs) != 3 {
		t.Fatalf("expected user1 to act as 3 groups, got %d", len(canActAs))
	}

	groupIds := make(map[string]bool)
	for _, g := range canActAs {
		groupIds[g.Id] = true
	}
	if !groupIds["groupA"] || !groupIds["groupB"] || !groupIds["groupC"] {
		t.Fatal("expected user1 to act as groupA, groupB, and groupC")
	}
}

func TestGetGroupsGroupCanActAs(t *testing.T) {
	store := createTestStore(t)

	// Create hierarchy: groupA -> groupB -> groupC
	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
	err := store.CreateUser(nil, owner1)
	if err != nil {
		t.Fatal(err)
	}

	groups := []Group{
		{Id: "groupA", Title: "Group A", Description: "Group A"},
		{Id: "groupB", Title: "Group B", Description: "Group B"},
		{Id: "groupC", Title: "Group C", Description: "Group C"},
	}

	for _, g := range groups {
		err = store.CreateGroup(nil, "owner1", g)
		if err != nil {
			t.Fatal(err)
		}
	}

	// Build hierarchy: groupA member of groupB, groupB member of groupC
	err = store.AddMemberGroup(nil, "groupB", "groupA")
	if err != nil {
		t.Fatal(err)
	}
	err = store.AddMemberGroup(nil, "groupC", "groupB")
	if err != nil {
		t.Fatal(err)
	}

	// groupA should be able to act as groupB and groupC (but not itself)
	canActAs, err := store.GetGroupsGroupCanActAs(nil, "groupA")
	if err != nil {
		t.Fatal(err)
	}

	if len(canActAs) != 2 {
		t.Fatalf("expected groupA to act as 2 groups, got %d", len(canActAs))
	}

	groupIds := make(map[string]bool)
	for _, g := range canActAs {
		groupIds[g.Id] = true
	}
	if !groupIds["groupB"] || !groupIds["groupC"] {
		t.Fatal("expected groupA to act as groupB and groupC")
	}
}

func TestAddUserPublicKey(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
		err = store.AddUserPublicKey(nil, "user1", publicKey)
		if err != nil {
			t.Fatal(err)
		}

		// Verify the key was added
		keys, err := store.GetUserPublicKeys(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if len(keys) != 1 || keys[0] != publicKey {
			t.Fatalf("expected 1 key, got %d: %v", len(keys), keys)
		}
	})

	t.Run("duplicate_key", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
		err = store.AddUserPublicKey(nil, "user1", publicKey)
		if err != nil {
			t.Fatal(err)
		}

		// Adding the same key again should fail
		err = store.AddUserPublicKey(nil, "user1", publicKey)
		if err == nil {
			t.Fatal("expected error for duplicate public key")
		}
	})

	t.Run("nonexistent_user", func(t *testing.T) {
		store := createTestStore(t)
		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
		err := store.AddUserPublicKey(nil, "nonexistent", publicKey)
		if err == nil {
			t.Fatal("expected error for nonexistent user")
		}
	})
}

func TestGetUserPublicKeys(t *testing.T) {
	t.Run("success_multiple_keys", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		keys := []string{
			"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ1... user1@example.com",
			"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ2... user1@work.com",
			"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... user1@laptop",
		}

		// Add multiple keys
		for _, key := range keys {
			err = store.AddUserPublicKey(nil, "user1", key)
			if err != nil {
				t.Fatal(err)
			}
		}

		// Retrieve all keys
		retrievedKeys, err := store.GetUserPublicKeys(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}

		if len(retrievedKeys) != len(keys) {
			t.Fatalf("expected %d keys, got %d", len(keys), len(retrievedKeys))
		}

		// Verify all keys are present
		keyMap := make(map[string]bool)
		for _, key := range retrievedKeys {
			keyMap[key] = true
		}
		for _, expectedKey := range keys {
			if !keyMap[expectedKey] {
				t.Fatalf("expected key not found: %s", expectedKey)
			}
		}
	})

	t.Run("no_keys", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		keys, err := store.GetUserPublicKeys(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if len(keys) != 0 {
			t.Fatalf("expected 0 keys for user with no keys, got %d", len(keys))
		}
	})

	t.Run("nonexistent_user", func(t *testing.T) {
		store := createTestStore(t)
		keys, err := store.GetUserPublicKeys(nil, "nonexistent")
		if err != nil {
			t.Fatal(err)
		}
		if len(keys) != 0 {
			t.Fatalf("expected 0 keys for nonexistent user, got %d", len(keys))
		}
	})
}

func TestRemoveUserPublicKey(t *testing.T) {
	t.Run("success", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
		err = store.AddUserPublicKey(nil, "user1", publicKey)
		if err != nil {
			t.Fatal(err)
		}

		err = store.RemoveUserPublicKey(nil, "user1", publicKey)
		if err != nil {
			t.Fatal(err)
		}

		// Verify key was removed
		keys, err := store.GetUserPublicKeys(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if len(keys) != 0 {
			t.Fatalf("expected 0 keys after removal, got %d", len(keys))
		}

		// Should be able to add the same key again after removal
		err = store.AddUserPublicKey(nil, "user1", publicKey)
		if err != nil {
			t.Fatal(err)
		}

		// Verify key was re-added
		keys, err = store.GetUserPublicKeys(nil, "user1")
		if err != nil {
			t.Fatal(err)
		}
		if len(keys) != 1 || keys[0] != publicKey {
			t.Fatalf("expected 1 key after re-adding, got %d: %v", len(keys), keys)
		}
	})

	t.Run("nonexistent_key", func(t *testing.T) {
		store := createTestStore(t)
		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
		err := store.CreateUser(nil, user1)
		if err != nil {
			t.Fatal(err)
		}

		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
		// Try to remove a key that was never added
		err = store.RemoveUserPublicKey(nil, "user1", publicKey)
		// This should succeed (no error) even if the key doesn't exist
		if err != nil {
			t.Fatal(err)
		}
	})
}

func TestTransactionRollback(t *testing.T) {
	store := createTestStore(t)
	db := store.(*SQLiteStore).db

	tx, err := db.Begin()
	if err != nil {
		t.Fatal(err)
	}
	defer tx.Rollback()

	// Create a user within the transaction
	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
	err = store.CreateUser(tx, user1)
	if err != nil {
		t.Fatal(err)
	}

	// Rollback the transaction
	if err := tx.Rollback(); err != nil {
		t.Fatal(err)
	}

	// User should not exist after rollback
	_, err = store.GetUser(nil, "user1")
	if err == nil {
		t.Fatal("expected user to not exist after transaction rollback")
	}
}

func TestConcurrentAccess(t *testing.T) {
	// Skip this test as SQLite in-memory databases don't handle true concurrency well
	// This test would be more appropriate for integration testing with a real database
	t.Skip("Skipping concurrent access test for in-memory SQLite database")
}
