package perm

import (
	"sort"
	"testing"

	"code.justin.tv/beefcake/server/rpc/beefcake"
	"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestAttachedPermissions(t *testing.T) {
	t.Run("Marshal and Unmarshal", func(t *testing.T) {
		testPermission := func() *beefcake.Permission {
			return &beefcake.Permission{Value: &beefcake.Permission_Legacy{
				Legacy: &beefcake.Permission_LegacyPermission{
					Id:   "p-id",
					Name: "p-name",
				},
			}}
		}

		testAttachedPermissions := func() AttachedPermissions {
			return AttachedPermissions([]*beefcake.AttachedPermission{
				{
					Id:         "id",
					Permission: testPermission(),
				},
			})
		}

		marshalled, err := dynamodbattribute.Marshal(testAttachedPermissions())
		require.NoError(t, err)

		var unmarshalled AttachedPermissions
		require.NoError(t, dynamodbattribute.Unmarshal(marshalled, &unmarshalled))
		assert.Equal(t, testAttachedPermissions(), unmarshalled)
	})

	t.Run("Sort", func(t *testing.T) {
		tcs := []struct {
			Name     string
			Value    []*beefcake.AttachedPermission
			Expected []*beefcake.AttachedPermission
		}{
			{
				Name:     "no permissions",
				Value:    []*beefcake.AttachedPermission{},
				Expected: []*beefcake.AttachedPermission{},
			},
			{
				Name: "one permissions",
				Value: []*beefcake.AttachedPermission{
					{Id: "id1", Permission: &beefcake.Permission{}},
				},
				Expected: []*beefcake.AttachedPermission{
					{Id: "id1", Permission: &beefcake.Permission{}},
				},
			},
			{
				Name: "several permissions should be sorted by id",
				Value: []*beefcake.AttachedPermission{
					{Id: "id2", Permission: &beefcake.Permission{}},
					{Id: "id1", Permission: &beefcake.Permission{}},
					{Id: "id3", Permission: &beefcake.Permission{}},
				},
				Expected: []*beefcake.AttachedPermission{
					{Id: "id1", Permission: &beefcake.Permission{}},
					{Id: "id2", Permission: &beefcake.Permission{}},
					{Id: "id3", Permission: &beefcake.Permission{}},
				},
			},
		}

		for _, tc := range tcs {
			t.Run(tc.Name, func(t *testing.T) {
				sort.Sort(AttachedPermissions(tc.Value))
				assert.Equal(t, tc.Expected, tc.Value)
			})
		}
	})
}
