package user

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"
)

// RoleMemberships represents a set of roles for a user
type RoleMemberships []*beefcake.User_RoleMembership

// Len implements sort.Interface
func (r RoleMemberships) Len() int { return len(r) }

// Less implements sort.Interface
func (r RoleMemberships) Less(i, j int) bool { return strings.Compare(r[i].GetId(), r[j].GetId()) < 0 }

// Swap implements sort.Interface
func (r RoleMemberships) Swap(i, j int) { r[i], r[j] = r[j], r[i] }

// MarshalDynamoDBAttributeValue implements dynamodbattribute.Marshaller
func (r RoleMemberships) MarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
	out := make(map[string]roleMembership, len(r))
	for _, userRole := range r {
		out[userRole.GetId()] = roleMembership(*userRole)
	}

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

	*av = *res
	return nil
}

// UnmarshalDynamoDBAttributeValue implements dynamodbattribute.Unmarshaller
func (r *RoleMemberships) UnmarshalDynamoDBAttributeValue(av *dynamodb.AttributeValue) error {
	var out map[string]roleMembership

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

	roles := make([]*beefcake.User_RoleMembership, 0, len(out))
	for _, role := range out {
		br := beefcake.User_RoleMembership(role)
		roles = append(roles, &br)
	}

	*r = RoleMemberships(roles)
	sort.Sort(r)

	return nil
}
