package kb

import (
	"context"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestKBServiceKnowledgeBaseTaxonomyLifecycle(t *testing.T) {
	ctx := context.Background()
	svc := newKBServiceForTest(t)

	taxonomy, err := svc.ListKnowledgeBaseTaxonomy(ctx, "wsp_1", "owner")
	require.NoError(t, err)
	require.Len(t, taxonomy.Groups, 1)
	require.True(t, taxonomy.Groups[0].IsDefault)
	defaultGroupID := taxonomy.Groups[0].ID
	deleteDefaultErr := svc.DeleteKnowledgeBaseGroup(ctx, "wsp_1", "owner", defaultGroupID)
	require.ErrorIs(t, deleteDefaultErr, ErrInvalidArgument)
	require.Equal(t, kbTaxonomyDefaultGroupDeleteCode, Code(deleteDefaultErr))

	group, err := svc.CreateKnowledgeBaseGroup(ctx, "wsp_1", "owner", KnowledgeBaseTaxonomyMutation{Name: "Operations", Color: "#123abc"})
	require.NoError(t, err)
	require.Equal(t, "#123ABC", group.Color)
	_, err = svc.CreateKnowledgeBaseGroup(ctx, "wsp_1", "owner", KnowledgeBaseTaxonomyMutation{Name: "operations"})
	require.ErrorIs(t, err, ErrInvalidArgument)
	require.Equal(t, kbTaxonomyGroupNameExistsCode, Code(err))
	production, err := svc.CreateKnowledgeBaseTag(ctx, "wsp_1", "owner", KnowledgeBaseTaxonomyMutation{Name: "Production"})
	require.NoError(t, err)
	_, err = svc.CreateKnowledgeBaseTag(ctx, "wsp_1", "owner", KnowledgeBaseTaxonomyMutation{Name: "production"})
	require.ErrorIs(t, err, ErrInvalidArgument)
	require.Equal(t, kbTaxonomyTagNameExistsCode, Code(err))
	runbook, err := svc.CreateKnowledgeBaseTag(ctx, "wsp_1", "owner", KnowledgeBaseTaxonomyMutation{Name: "Runbook"})
	require.NoError(t, err)
	otherWorkspaceGroup, err := svc.CreateKnowledgeBaseGroup(ctx, "wsp_2", "owner", KnowledgeBaseTaxonomyMutation{Name: "Other workspace"})
	require.NoError(t, err)
	otherWorkspaceTag, err := svc.CreateKnowledgeBaseTag(ctx, "wsp_2", "owner", KnowledgeBaseTaxonomyMutation{Name: "Other workspace"})
	require.NoError(t, err)
	_, err = svc.CreateKnowledgeBase(ctx, "wsp_1", "owner", KBMutation{Name: "Cross-workspace group", GroupID: &otherWorkspaceGroup.ID})
	require.ErrorIs(t, err, ErrInvalidArgument)
	_, err = svc.CreateKnowledgeBase(ctx, "wsp_1", "owner", KBMutation{Name: "Cross-workspace tag", TagIDs: []string{otherWorkspaceTag.ID}})
	require.ErrorIs(t, err, ErrInvalidArgument)

	base, err := svc.CreateKnowledgeBase(ctx, "wsp_1", "owner", KBMutation{Name: "Incident response", GroupID: &group.ID, TagIDs: []string{production.ID, runbook.ID}})
	require.NoError(t, err)
	require.Equal(t, group.ID, base.GroupID)
	require.Equal(t, group.Name, base.Group.Name)
	require.Len(t, base.Tags, 2)
	_, err = svc.UpsertKnowledgeBasePermission(ctx, "wsp_1", "owner", base.ID, KBPermissionGrantMutation{SubjectType: "user", SubjectID: "viewer", Role: "view"})
	require.NoError(t, err)

	page, err := svc.ListKnowledgeBases(ctx, "wsp_1", "owner", "all", "production", []string{production.ID, runbook.ID}, 1, 20)
	require.NoError(t, err)
	require.Len(t, page.Items, 1)
	require.Equal(t, base.ID, page.Items[0].ID)

	_, err = svc.UpdateKnowledgeBase(ctx, "wsp_1", "viewer", base.ID, KBMutation{Name: base.Name, GroupID: &defaultGroupID})
	require.ErrorIs(t, err, ErrForbidden)

	require.NoError(t, svc.DeleteKnowledgeBaseGroup(ctx, "wsp_1", "owner", group.ID))
	reassigned, err := svc.GetKnowledgeBase(ctx, "wsp_1", "owner", base.ID)
	require.NoError(t, err)
	require.Equal(t, defaultGroupID, reassigned.GroupID)

	require.NoError(t, svc.DeleteKnowledgeBaseTag(ctx, "wsp_1", "owner", production.ID))
	remaining, err := svc.GetKnowledgeBase(ctx, "wsp_1", "owner", base.ID)
	require.NoError(t, err)
	require.Len(t, remaining.Tags, 1)
	require.Equal(t, runbook.ID, remaining.Tags[0].ID)

	tooManyTagFilters := make([]string, 0, maxKnowledgeBaseTagsPerBase+1)
	for index := 0; index <= maxKnowledgeBaseTagsPerBase; index++ {
		tooManyTagFilters = append(tooManyTagFilters, string(rune('a'+index)))
	}
	_, err = svc.ListKnowledgeBases(ctx, "wsp_1", "owner", "all", "", tooManyTagFilters, 1, 20)
	require.ErrorIs(t, err, ErrInvalidArgument)
}
