// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package sns

import (
	"context"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/internal/awsutil"
)

// Input for Subscribe action.
type SubscribeInput struct {
	_ struct{} `type:"structure"`

	// A map of attributes with their corresponding values.
	//
	// The following lists the names, descriptions, and values of the special request
	// parameters that the SetTopicAttributes action uses:
	//
	//    * DeliveryPolicy – The policy that defines how Amazon SNS retries failed
	//    deliveries to HTTP/S endpoints.
	//
	//    * FilterPolicy – The simple JSON object that lets your subscriber receive
	//    only a subset of messages, rather than receiving every message published
	//    to the topic.
	//
	//    * RawMessageDelivery – When set to true, enables raw message delivery
	//    to Amazon SQS or HTTP/S endpoints. This eliminates the need for the endpoints
	//    to process JSON formatting, which is otherwise created for Amazon SNS
	//    metadata.
	//
	//    * RedrivePolicy – When specified, sends undeliverable messages to the
	//    specified Amazon SQS dead-letter queue. Messages that can't be delivered
	//    due to client errors (for example, when the subscribed endpoint is unreachable)
	//    or server errors (for example, when the service that powers the subscribed
	//    endpoint becomes unavailable) are held in the dead-letter queue for further
	//    analysis or reprocessing.
	Attributes map[string]string `type:"map"`

	// The endpoint that you want to receive notifications. Endpoints vary by protocol:
	//
	//    * For the http protocol, the endpoint is an URL beginning with http://
	//
	//    * For the https protocol, the endpoint is a URL beginning with https://
	//
	//    * For the email protocol, the endpoint is an email address
	//
	//    * For the email-json protocol, the endpoint is an email address
	//
	//    * For the sms protocol, the endpoint is a phone number of an SMS-enabled
	//    device
	//
	//    * For the sqs protocol, the endpoint is the ARN of an Amazon SQS queue
	//
	//    * For the application protocol, the endpoint is the EndpointArn of a mobile
	//    app and device.
	//
	//    * For the lambda protocol, the endpoint is the ARN of an Amazon Lambda
	//    function.
	Endpoint *string `type:"string"`

	// The protocol you want to use. Supported protocols include:
	//
	//    * http – delivery of JSON-encoded message via HTTP POST
	//
	//    * https – delivery of JSON-encoded message via HTTPS POST
	//
	//    * email – delivery of message via SMTP
	//
	//    * email-json – delivery of JSON-encoded message via SMTP
	//
	//    * sms – delivery of message via SMS
	//
	//    * sqs – delivery of JSON-encoded message to an Amazon SQS queue
	//
	//    * application – delivery of JSON-encoded message to an EndpointArn for
	//    a mobile app and device.
	//
	//    * lambda – delivery of JSON-encoded message to an Amazon Lambda function.
	//
	// Protocol is a required field
	Protocol *string `type:"string" required:"true"`

	// Sets whether the response from the Subscribe request includes the subscription
	// ARN, even if the subscription is not yet confirmed.
	//
	//    * If you have the subscription ARN returned, the response includes the
	//    ARN in all cases, even if the subscription is not yet confirmed.
	//
	//    * If you don't have the subscription ARN returned, in addition to the
	//    ARN for confirmed subscriptions, the response also includes the pending
	//    subscription ARN value for subscriptions that aren't yet confirmed. A
	//    subscription becomes confirmed when the subscriber calls the ConfirmSubscription
	//    action with a confirmation token.
	//
	// If you set this parameter to true, .
	//
	// The default value is false.
	ReturnSubscriptionArn *bool `type:"boolean"`

	// The ARN of the topic you want to subscribe to.
	//
	// TopicArn is a required field
	TopicArn *string `type:"string" required:"true"`
}

// String returns the string representation
func (s SubscribeInput) String() string {
	return awsutil.Prettify(s)
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SubscribeInput) Validate() error {
	invalidParams := aws.ErrInvalidParams{Context: "SubscribeInput"}

	if s.Protocol == nil {
		invalidParams.Add(aws.NewErrParamRequired("Protocol"))
	}

	if s.TopicArn == nil {
		invalidParams.Add(aws.NewErrParamRequired("TopicArn"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// Response for Subscribe action.
type SubscribeOutput struct {
	_ struct{} `type:"structure"`

	// The ARN of the subscription if it is confirmed, or the string "pending confirmation"
	// if the subscription requires confirmation. However, if the API request parameter
	// ReturnSubscriptionArn is true, then the value is always the subscription
	// ARN, even if the subscription requires confirmation.
	SubscriptionArn *string `type:"string"`
}

// String returns the string representation
func (s SubscribeOutput) String() string {
	return awsutil.Prettify(s)
}

const opSubscribe = "Subscribe"

// SubscribeRequest returns a request value for making API operation for
// Amazon Simple Notification Service.
//
// Prepares to subscribe an endpoint by sending the endpoint a confirmation
// message. To actually create a subscription, the endpoint owner must call
// the ConfirmSubscription action with the token from the confirmation message.
// Confirmation tokens are valid for three days.
//
// This action is throttled at 100 transactions per second (TPS).
//
//    // Example sending a request using SubscribeRequest.
//    req := client.SubscribeRequest(params)
//    resp, err := req.Send(context.TODO())
//    if err == nil {
//        fmt.Println(resp)
//    }
//
// Please also see https://docs.aws.amazon.com/goto/WebAPI/sns-2010-03-31/Subscribe
func (c *Client) SubscribeRequest(input *SubscribeInput) SubscribeRequest {
	op := &aws.Operation{
		Name:       opSubscribe,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SubscribeInput{}
	}

	req := c.newRequest(op, input, &SubscribeOutput{})
	return SubscribeRequest{Request: req, Input: input, Copy: c.SubscribeRequest}
}

// SubscribeRequest is the request type for the
// Subscribe API operation.
type SubscribeRequest struct {
	*aws.Request
	Input *SubscribeInput
	Copy  func(*SubscribeInput) SubscribeRequest
}

// Send marshals and sends the Subscribe API request.
func (r SubscribeRequest) Send(ctx context.Context) (*SubscribeResponse, error) {
	r.Request.SetContext(ctx)
	err := r.Request.Send()
	if err != nil {
		return nil, err
	}

	resp := &SubscribeResponse{
		SubscribeOutput: r.Request.Data.(*SubscribeOutput),
		response:        &aws.Response{Request: r.Request},
	}

	return resp, nil
}

// SubscribeResponse is the response type for the
// Subscribe API operation.
type SubscribeResponse struct {
	*SubscribeOutput

	response *aws.Response
}

// SDKResponseMetdata returns the response metadata for the
// Subscribe request.
func (r *SubscribeResponse) SDKResponseMetdata() *aws.Response {
	return r.response
}
