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

package gamelift

import (
	"context"
	"fmt"

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

// Represents the input for a request action.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/gamelift-2015-10-01/StartMatchmakingInput
type StartMatchmakingInput struct {
	_ struct{} `type:"structure"`

	// Name of the matchmaking configuration to use for this request. Matchmaking
	// configurations must exist in the same region as this request.
	//
	// ConfigurationName is a required field
	ConfigurationName *string `min:"1" type:"string" required:"true"`

	// Information on each player to be matched. This information must include a
	// player ID, and may contain player attributes and latency data to be used
	// in the matchmaking process. After a successful match, Player objects contain
	// the name of the team the player is assigned to.
	//
	// Players is a required field
	Players []Player `type:"list" required:"true"`

	// Unique identifier for a matchmaking ticket. If no ticket ID is specified
	// here, Amazon GameLift will generate one in the form of a UUID. Use this identifier
	// to track the matchmaking ticket status and retrieve match results.
	TicketId *string `min:"1" type:"string"`
}

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

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

	if s.ConfigurationName == nil {
		invalidParams.Add(aws.NewErrParamRequired("ConfigurationName"))
	}
	if s.ConfigurationName != nil && len(*s.ConfigurationName) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("ConfigurationName", 1))
	}

	if s.Players == nil {
		invalidParams.Add(aws.NewErrParamRequired("Players"))
	}
	if s.TicketId != nil && len(*s.TicketId) < 1 {
		invalidParams.Add(aws.NewErrParamMinLen("TicketId", 1))
	}
	if s.Players != nil {
		for i, v := range s.Players {
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Players", i), err.(aws.ErrInvalidParams))
			}
		}
	}

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

// Represents the returned data in response to a request action.
// Please also see https://docs.aws.amazon.com/goto/WebAPI/gamelift-2015-10-01/StartMatchmakingOutput
type StartMatchmakingOutput struct {
	_ struct{} `type:"structure"`

	// Ticket representing the matchmaking request. This object include the information
	// included in the request, ticket status, and match results as generated during
	// the matchmaking process.
	MatchmakingTicket *MatchmakingTicket `type:"structure"`
}

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

const opStartMatchmaking = "StartMatchmaking"

// StartMatchmakingRequest returns a request value for making API operation for
// Amazon GameLift.
//
// Uses FlexMatch to create a game match for a group of players based on custom
// matchmaking rules, and starts a new game for the matched players. Each matchmaking
// request specifies the type of match to build (team configuration, rules for
// an acceptable match, etc.). The request also specifies the players to find
// a match for and where to host the new game session for optimal performance.
// A matchmaking request might start with a single player or a group of players
// who want to play together. FlexMatch finds additional players as needed to
// fill the match. Match type, rules, and the queue used to place a new game
// session are defined in a MatchmakingConfiguration. For complete information
// on setting up and using FlexMatch, see the topic Adding FlexMatch to Your
// Game (https://docs.aws.amazon.com/gamelift/latest/developerguide/match-intro.html).
//
// To start matchmaking, provide a unique ticket ID, specify a matchmaking configuration,
// and include the players to be matched. You must also include a set of player
// attributes relevant for the matchmaking configuration. If successful, a matchmaking
// ticket is returned with status set to QUEUED. Track the status of the ticket
// to respond as needed and acquire game session connection information for
// successfully completed matches.
//
// Tracking ticket status -- A couple of options are available for tracking
// the status of matchmaking requests:
//
//    * Polling -- Call DescribeMatchmaking. This operation returns the full
//    ticket object, including current status and (for completed tickets) game
//    session connection info. We recommend polling no more than once every
//    10 seconds.
//
//    * Notifications -- Get event notifications for changes in ticket status
//    using Amazon Simple Notification Service (SNS). Notifications are easy
//    to set up (see CreateMatchmakingConfiguration) and typically deliver match
//    status changes faster and more efficiently than polling. We recommend
//    that you use polling to back up to notifications (since delivery is not
//    guaranteed) and call DescribeMatchmaking only when notifications are not
//    received within 30 seconds.
//
// Processing a matchmaking request -- FlexMatch handles a matchmaking request
// as follows:
//
// Your client code submits a StartMatchmaking request for one or more players
// and tracks the status of the request ticket.
//
// FlexMatch uses this ticket and others in process to build an acceptable match.
// When a potential match is identified, all tickets in the proposed match are
// advanced to the next status.
//
// If the match requires player acceptance (set in the matchmaking configuration),
// the tickets move into status REQUIRES_ACCEPTANCE. This status triggers your
// client code to solicit acceptance from all players in every ticket involved
// in the match, and then call AcceptMatch for each player. If any player rejects
// or fails to accept the match before a specified timeout, the proposed match
// is dropped (see AcceptMatch for more details).
//
// Once a match is proposed and accepted, the matchmaking tickets move into
// status PLACING. FlexMatch locates resources for a new game session using
// the game session queue (set in the matchmaking configuration) and creates
// the game session based on the match data.
//
// When the match is successfully placed, the matchmaking tickets move into
// COMPLETED status. Connection information (including game session endpoint
// and player session) is added to the matchmaking tickets. Matched players
// can use the connection information to join the game.
//
//    * StartMatchmaking
//
//    * DescribeMatchmaking
//
//    * StopMatchmaking
//
//    * AcceptMatch
//
//    * StartMatchBackfill
//
//    // Example sending a request using StartMatchmakingRequest.
//    req := client.StartMatchmakingRequest(params)
//    resp, err := req.Send(context.TODO())
//    if err == nil {
//        fmt.Println(resp)
//    }
//
// Please also see https://docs.aws.amazon.com/goto/WebAPI/gamelift-2015-10-01/StartMatchmaking
func (c *Client) StartMatchmakingRequest(input *StartMatchmakingInput) StartMatchmakingRequest {
	op := &aws.Operation{
		Name:       opStartMatchmaking,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &StartMatchmakingInput{}
	}

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

// StartMatchmakingRequest is the request type for the
// StartMatchmaking API operation.
type StartMatchmakingRequest struct {
	*aws.Request
	Input *StartMatchmakingInput
	Copy  func(*StartMatchmakingInput) StartMatchmakingRequest
}

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

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

	return resp, nil
}

// StartMatchmakingResponse is the response type for the
// StartMatchmaking API operation.
type StartMatchmakingResponse struct {
	*StartMatchmakingOutput

	response *aws.Response
}

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