// Code generated by smithy-go-codegen DO NOT EDIT.

package evidently

import (
	"context"
	awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
	"github.com/aws/aws-sdk-go-v2/aws/signer/v4"
	"github.com/aws/aws-sdk-go-v2/service/evidently/types"
	"github.com/aws/smithy-go/middleware"
	smithyhttp "github.com/aws/smithy-go/transport/http"
)

// Creates an Evidently experiment. Before you create an experiment, you must
// create the feature to use for the experiment. An experiment helps you make
// feature design decisions based on evidence and data. An experiment can test as
// many as five variations at once. Evidently collects experiment data and analyzes
// it by statistical methods, and provides clear recommendations about which
// variations perform better. You can optionally specify a segment to have the
// experiment consider only certain audience types in the experiment, such as using
// only user sessions from a certain location or who use a certain internet
// browser. Don't use this operation to update an existing experiment. Instead, use
// UpdateExperiment
// (https://docs.aws.amazon.com/cloudwatchevidently/latest/APIReference/API_UpdateExperiment.html).
func (c *Client) CreateExperiment(ctx context.Context, params *CreateExperimentInput, optFns ...func(*Options)) (*CreateExperimentOutput, error) {
	if params == nil {
		params = &CreateExperimentInput{}
	}

	result, metadata, err := c.invokeOperation(ctx, "CreateExperiment", params, optFns, c.addOperationCreateExperimentMiddlewares)
	if err != nil {
		return nil, err
	}

	out := result.(*CreateExperimentOutput)
	out.ResultMetadata = metadata
	return out, nil
}

type CreateExperimentInput struct {

	// An array of structures that defines the metrics used for the experiment, and
	// whether a higher or lower value for each metric is the goal.
	//
	// This member is required.
	MetricGoals []types.MetricGoalConfig

	// A name for the new experiment.
	//
	// This member is required.
	Name *string

	// The name or ARN of the project that you want to create the new experiment in.
	//
	// This member is required.
	Project *string

	// An array of structures that describe the configuration of each feature variation
	// used in the experiment.
	//
	// This member is required.
	Treatments []types.TreatmentConfig

	// An optional description of the experiment.
	Description *string

	// A structure that contains the configuration of which variation to use as the
	// "control" version. tThe "control" version is used for comparison with other
	// variations. This structure also specifies how much experiment traffic is
	// allocated to each variation.
	OnlineAbConfig *types.OnlineAbConfig

	// When Evidently assigns a particular user session to an experiment, it must use a
	// randomization ID to determine which variation the user session is served. This
	// randomization ID is a combination of the entity ID and randomizationSalt. If you
	// omit randomizationSalt, Evidently uses the experiment name as the
	// randomizationSalt.
	RandomizationSalt *string

	// The portion of the available audience that you want to allocate to this
	// experiment, in thousandths of a percent. The available audience is the total
	// audience minus the audience that you have allocated to overrides or current
	// launches of this feature. This is represented in thousandths of a percent. For
	// example, specify 10,000 to allocate 10% of the available audience.
	SamplingRate int64

	// Specifies an audience segment to use in the experiment. When a segment is used
	// in an experiment, only user sessions that match the segment pattern are used in
	// the experiment.
	Segment *string

	// Assigns one or more tags (key-value pairs) to the experiment. Tags can help you
	// organize and categorize your resources. You can also use them to scope user
	// permissions by granting a user permission to access or change only resources
	// with certain tag values. Tags don't have any semantic meaning to Amazon Web
	// Services and are interpreted strictly as strings of characters. You can
	// associate as many as 50 tags with an experiment. For more information, see
	// Tagging Amazon Web Services resources
	// (https://docs.aws.amazon.com/general/latest/gr/aws_tagging.html).
	Tags map[string]string

	noSmithyDocumentSerde
}

type CreateExperimentOutput struct {

	// A structure containing the configuration details of the experiment that you
	// created.
	//
	// This member is required.
	Experiment *types.Experiment

	// Metadata pertaining to the operation's result.
	ResultMetadata middleware.Metadata

	noSmithyDocumentSerde
}

func (c *Client) addOperationCreateExperimentMiddlewares(stack *middleware.Stack, options Options) (err error) {
	err = stack.Serialize.Add(&awsRestjson1_serializeOpCreateExperiment{}, middleware.After)
	if err != nil {
		return err
	}
	err = stack.Deserialize.Add(&awsRestjson1_deserializeOpCreateExperiment{}, middleware.After)
	if err != nil {
		return err
	}
	if err = addSetLoggerMiddleware(stack, options); err != nil {
		return err
	}
	if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil {
		return err
	}
	if err = addResolveEndpointMiddleware(stack, options); err != nil {
		return err
	}
	if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil {
		return err
	}
	if err = addRetryMiddlewares(stack, options); err != nil {
		return err
	}
	if err = addHTTPSignerV4Middleware(stack, options); err != nil {
		return err
	}
	if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil {
		return err
	}
	if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil {
		return err
	}
	if err = addClientUserAgent(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil {
		return err
	}
	if err = addOpCreateExperimentValidationMiddleware(stack); err != nil {
		return err
	}
	if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateExperiment(options.Region), middleware.Before); err != nil {
		return err
	}
	if err = addRequestIDRetrieverMiddleware(stack); err != nil {
		return err
	}
	if err = addResponseErrorMiddleware(stack); err != nil {
		return err
	}
	if err = addRequestResponseLogging(stack, options); err != nil {
		return err
	}
	return nil
}

func newServiceMetadataMiddleware_opCreateExperiment(region string) *awsmiddleware.RegisterServiceMetadata {
	return &awsmiddleware.RegisterServiceMetadata{
		Region:        region,
		ServiceID:     ServiceID,
		SigningName:   "evidently",
		OperationName: "CreateExperiment",
	}
}
