package role

import (
	"sort"
	"strings"

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

// UserMemberships represents a set of users
type UserMemberships []*beefcake.Role_UserMembership

func (u UserMemberships) Len() int { return len(u) }
func (u UserMemberships) Less(i, j int) bool {
	return strings.Compare(u[i].GetUserId(), u[j].GetUserId()) < 0
}
func (u UserMemberships) Swap(i, j int) { u[i], u[j] = u[j], u[i] }

// MarshalDynamoDBAttributeValue implements dynamodbattribute.Marshaller
func (u UserMemberships) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
	if len(u) == 0 {
		av.SetM(map[string]*dynamodb.AttributeValue{})
		return nil
	}

	out := make(map[string]UserMembership, len(u))
	for _, roleUser := range u {
		out[roleUser.GetUserId()] = UserMembership(*roleUser)
	}

	res, err := dynamodbattribute.Marshal(out)
	if err != nil {
		return err
	}

	*av = *res
	return nil
}

// UnmarshalDynamoDBAttributeValue implements dynamodbattribute.Unmarshaller
func (u *UserMemberships) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
	var out map[string]UserMembership

	if err := dynamodbattribute.Unmarshal(av, &out); err != nil {
		return err
	}

	users := make([]*beefcake.Role_UserMembership, 0, len(out))
	for _, roleUser := range out {
		br := beefcake.Role_UserMembership(roleUser)
		users = append(users, &br)
	}

	*u = UserMemberships(users)
	sort.Sort(u)

	return nil
}
