package handlers

import (
	"encoding/json"

	"github.com/fiskerinc/cloud-services/services/attendant/services"

	"github.com/fiskerinc/cloud-services/pkg/cache"
	"github.com/fiskerinc/cloud-services/pkg/common"
	"github.com/fiskerinc/cloud-services/pkg/logger"
	"github.com/fiskerinc/cloud-services/pkg/redis"
	"github.com/fiskerinc/cloud-services/pkg/validator"

	"github.com/pkg/errors"
)

func GetFileKeys(db *services.DB, device common.Device, id string, data []byte) error {
	logger.Debug().Msgf("GetFileKeys %v %s", device, id)
	var err error
	var req *common.FileKeysRequest

	client := services.RedisClientPool().GetFromPool()
	defer client.Close()

	req, err = parseGetFileKeysRequest(data)
	if err != nil {
		notifyFileKeysGeneralError(client, device, id, err)
		return err
	}

	keys, err := cache.RetrieveFileEncryptionParams(client, db.GetFileKeys(), req.FileIDs)
	if err != nil {
		notifyFileKeysGeneralError(client, device, id, err)
		return err
	}

	err = client.SafeQueueMessage(device.Key(id), common.Message{
		Handler: "filekeys",
		Data:    keys,
	})

	if err != nil {
		return err
	}

	logger.Debug().Msgf("GetFileKeys sent %v %s", device, id)

	return nil
}

func parseGetFileKeysRequest(data []byte) (*common.FileKeysRequest, error) {
	var status common.FileKeysRequest

	err := json.Unmarshal(data, &status)
	if err != nil {
		return nil, errors.WithStack(err)
	}

	err = validator.ValidateStruct(status)
	if err != nil {
		return &status, errors.WithStack(err)
	}

	return &status, nil
}

func notifyFileKeysGeneralError(client redis.Client, device common.Device, id string, err error) {
	e := client.SafePublishMessage(device.Key(id), common.Message{
		Handler: "filekeys",
		Data: []common.FileKeyResponse{
			{
				FileID: "0",
				Error:  err.Error(),
			},
		},
	})
	if e != nil {
		logger.Error().Err(errors.WithStack(e)).Send()
	}
}
