package sns

import (
	"context"
	"encoding/json"

	"code.justin.tv/creator-collab/log/errors"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sns"
)

type Client interface {
	SendToTopic(ctx context.Context, message interface{}) error
}

// NewClient creates an instance of an sns client
func NewClient(awsSession *session.Session, topic string) Client {
	return &clientImpl{
		SNSClient: sns.New(awsSession),
		Topic:     topic,
	}
}

// clientImpl is a wrapper for the snsClient.
type clientImpl struct {
	SNSClient *sns.SNS
	Topic     string
}

// SendToTopic sends a message to the specified topic
func (c *clientImpl) SendToTopic(ctx context.Context, message interface{}) error {
	json, err := json.Marshal(message)
	if err != nil {
		return errors.Wrap(err, "sns - send - marhsal failed")
	}

	input := &sns.PublishInput{
		Message:  aws.String(string(json)),
		TopicArn: aws.String(c.Topic),
	}

	_, err = c.SNSClient.PublishWithContext(ctx, input)
	if err != nil {
		return errors.Wrap(err, "sns - send - publish failed", errors.Fields{
			"msg":   string(json),
			"topic": c.Topic,
		})
	}

	return nil
}
