package main

import (
	"context"
	"log"

	"code.justin.tv/beefcake/server/internal/config"
	"code.justin.tv/beefcake/server/internal/legacyperm"
	"code.justin.tv/beefcake/server/internal/role/roleiface"
	"code.justin.tv/beefcake/server/internal/stringutil"
	"code.justin.tv/beefcake/server/rpc/beefcake"
	"github.com/aws/aws-lambda-go/events"
)

type handler struct {
	Config *config.Config
	Roles  roleiface.RolesAPI
}

func (h *handler) Handle(ctx context.Context, event events.DynamoDBEvent) error {
	for _, record := range event.Records {
		if err := h.handleRecord(ctx, record); err != nil {
			return err
		}
	}
	return nil
}

func (h *handler) handleRecord(ctx context.Context, record events.DynamoDBEventRecord) error {
	rolesRemoved := h.roleIDs(record.Change.OldImage)
	newRoles := h.roleIDs(record.Change.NewImage)
	for r := range newRoles {
		rolesRemoved.Remove(r)
	}

	if len(rolesRemoved) > 0 {
		for r := range rolesRemoved {
			permID := h.permID(record.Change.OldImage)
			log.Printf("Removing permission<id=%s> from role<%v>", permID, rolesRemoved)
			if err := h.Roles.RemoveLegacyPermissionDetails(ctx, r, permID); err != nil {
				return err
			}
		}
	}

	if len(newRoles) > 0 {
		permID := h.permID(record.Change.NewImage)
		permName := h.permName(record.Change.NewImage)
		log.Printf("Adding permission<id=%s,name=%s> to roles<%v>", permID, permName, newRoles)
		for r := range newRoles {
			if err := h.Roles.AddLegacyPermissionDetails(ctx, r, &beefcake.Permission_LegacyPermission{
				Id:   permID,
				Name: permName,
			}); err != nil {
				return err
			}
		}
	}

	return nil
}

func (h *handler) roleIDs(av map[string]events.DynamoDBAttributeValue) stringutil.Set {
	out := stringutil.NewSet()

	raw, ok := av[legacyperm.RolesAttribute]
	if !ok {
		return out
	}

	for item := range raw.Map() {
		out.Add(item)
	}

	return out
}

func (h *handler) permID(av map[string]events.DynamoDBAttributeValue) string {
	return av[h.Config.LegacyPermissionsHashKey.Get()].String()
}

func (h *handler) permName(av map[string]events.DynamoDBAttributeValue) string {
	return av[legacyperm.NameAttribute].String()
}
