package resource

import (
	"context"
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
	"github.com/pkg/errors"

	"code.justin.tv/eventbus/controlplane/e2e/internal/e2eutil"
	"code.justin.tv/eventbus/controlplane/e2e/internal/report"
	"code.justin.tv/eventbus/controlplane/internal/e2eaccounts"
	"code.justin.tv/eventbus/controlplane/internal/sqsutil"
)

const defaultPolicy = `{
"Version": "2012-10-17",
"Statement": [{
  "Sid": "eventbus",
  "Effect": "Allow",
  "Principal": "*",
  "Action": "sqs:SendMessage",
  "Resource": "*",
  "Condition":{
    "ArnEquals":{
      "aws:SourceArn": "arn:aws:*:*:` + e2eaccounts.MainAccountID + `:*"
    }
  }
}]
}`

func reportErrorSlice(ctx context.Context, msg string, err error) []report.Error {
	return []report.Error{report.ErrorFromContext(ctx, msg, err)}
}

type BYOQResult struct {
	QueueURL           string
	DeadletterQueueURL string
	DeadletterQueueARN string
}

func createBYOQueue(ctx context.Context, givenName string) (*BYOQResult, error) {
	sess := session.Must(session.NewSession())
	sqsClient := sqs.New(sess, e2eaccounts.AccountCredentials().SubscriberConfig())
	queueName := fmt.Sprintf("EventBus-byoq-%s-%s", givenName, e2eutil.JobID(ctx))
	kmsKeyID := fmt.Sprintf("arn:aws:kms:us-west-2:%s:key/76c58211-8657-4fd9-b44e-fe454c55bbaa", e2eaccounts.MainAccountID)

	dlqResp, err := sqsClient.CreateQueueWithContext(ctx, &sqs.CreateQueueInput{
		QueueName: aws.String(queueName + "-dlq"),
		Attributes: aws.StringMap(map[string]string{
			sqsutil.KeyPolicy:   defaultPolicy,
			sqsutil.KeyKMSKeyID: kmsKeyID,
		}),
	})
	if err != nil {
		return nil, errors.Wrap(err, "could not register BYOQ deadletter")
	}

	attrResp, err := sqsClient.GetQueueAttributesWithContext(ctx, &sqs.GetQueueAttributesInput{
		QueueUrl:       dlqResp.QueueUrl,
		AttributeNames: aws.StringSlice([]string{sqsutil.KeyQueueARN}),
	})
	if err != nil {
		return nil, errors.Wrap(err, "could not get byoq attributes")
	}

	dlqARN := aws.StringValue(attrResp.Attributes[sqsutil.KeyQueueARN])
	if dlqARN == "" {
		return nil, errors.New("empty queue arn")
	}

	redrive := &sqsutil.RedrivePolicy{
		DeadletterTargetARN: dlqARN,
		MaxReceiveCount:     3,
	}
	redriveStr, err := redrive.ToStringAttribute()
	if err != nil {
		return nil, errors.Wrap(err, "could not encode redrive policy")
	}

	createResp, err := sqsClient.CreateQueueWithContext(ctx, &sqs.CreateQueueInput{
		QueueName: aws.String(queueName),
		Attributes: aws.StringMap(map[string]string{
			sqsutil.KeyPolicy:        defaultPolicy,
			sqsutil.KeyKMSKeyID:      kmsKeyID,
			sqsutil.KeyRedrivePolicy: redriveStr,
		}),
	})
	if err != nil {
		return nil, errors.Wrap(err, "could not register BYOQ queue")
	}

	return &BYOQResult{
		QueueURL:           aws.StringValue(createResp.QueueUrl),
		DeadletterQueueURL: aws.StringValue(dlqResp.QueueUrl),
		DeadletterQueueARN: dlqARN,
	}, nil
}
