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

package glacier

import (
	"context"
	"io"

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

// Provides options for downloading output of an Amazon Glacier job.
type GetJobOutputInput struct {
	_ struct{} `type:"structure"`

	// The AccountId value is the AWS account ID of the account that owns the vault.
	// You can either specify an AWS account ID or optionally a single '-' (hyphen),
	// in which case Amazon Glacier uses the AWS account ID associated with the
	// credentials used to sign the request. If you use an account ID, do not include
	// any hyphens ('-') in the ID.
	//
	// AccountId is a required field
	AccountId *string `location:"uri" locationName:"accountId" type:"string" required:"true"`

	// The job ID whose data is downloaded.
	//
	// JobId is a required field
	JobId *string `location:"uri" locationName:"jobId" type:"string" required:"true"`

	// The range of bytes to retrieve from the output. For example, if you want
	// to download the first 1,048,576 bytes, specify the range as bytes=0-1048575.
	// By default, this operation downloads the entire output.
	//
	// If the job output is large, then you can use a range to retrieve a portion
	// of the output. This allows you to download the entire output in smaller chunks
	// of bytes. For example, suppose you have 1 GB of job output you want to download
	// and you decide to download 128 MB chunks of data at a time, which is a total
	// of eight Get Job Output requests. You use the following process to download
	// the job output:
	//
	// Download a 128 MB chunk of output by specifying the appropriate byte range.
	// Verify that all 128 MB of data was received.
	//
	// Along with the data, the response includes a SHA256 tree hash of the payload.
	// You compute the checksum of the payload on the client and compare it with
	// the checksum you received in the response to ensure you received all the
	// expected data.
	//
	// Repeat steps 1 and 2 for all the eight 128 MB chunks of output data, each
	// time specifying the appropriate byte range.
	//
	// After downloading all the parts of the job output, you have a list of eight
	// checksum values. Compute the tree hash of these values to find the checksum
	// of the entire output. Using the DescribeJob API, obtain job information of
	// the job that provided you the output. The response includes the checksum
	// of the entire archive stored in Amazon Glacier. You compare this value with
	// the checksum you computed to ensure you have downloaded the entire archive
	// content with no errors.
	Range *string `location:"header" locationName:"Range" type:"string"`

	// The name of the vault.
	//
	// VaultName is a required field
	VaultName *string `location:"uri" locationName:"vaultName" type:"string" required:"true"`
}

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

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

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

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

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

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

// MarshalFields encodes the AWS API shape using the passed in protocol encoder.
func (s GetJobOutputInput) MarshalFields(e protocol.FieldEncoder) error {

	if s.Range != nil {
		v := *s.Range

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "Range", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.AccountId != nil {
		v := *s.AccountId

		metadata := protocol.Metadata{}
		e.SetValue(protocol.PathTarget, "accountId", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.JobId != nil {
		v := *s.JobId

		metadata := protocol.Metadata{}
		e.SetValue(protocol.PathTarget, "jobId", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.VaultName != nil {
		v := *s.VaultName

		metadata := protocol.Metadata{}
		e.SetValue(protocol.PathTarget, "vaultName", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	return nil
}

// Contains the Amazon Glacier response to your request.
type GetJobOutputOutput struct {
	_ struct{} `type:"structure" payload:"Body"`

	// Indicates the range units accepted. For more information, see RFC2616 (http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html).
	AcceptRanges *string `location:"header" locationName:"Accept-Ranges" type:"string"`

	// The description of an archive.
	ArchiveDescription *string `location:"header" locationName:"x-amz-archive-description" type:"string"`

	// The job data, either archive data or inventory data.
	Body io.ReadCloser `locationName:"body" type:"blob"`

	// The checksum of the data in the response. This header is returned only when
	// retrieving the output for an archive retrieval job. Furthermore, this header
	// appears only under the following conditions:
	//
	//    * You get the entire range of the archive.
	//
	//    * You request a range to return of the archive that starts and ends on
	//    a multiple of 1 MB. For example, if you have an 3.1 MB archive and you
	//    specify a range to return that starts at 1 MB and ends at 2 MB, then the
	//    x-amz-sha256-tree-hash is returned as a response header.
	//
	//    * You request a range of the archive to return that starts on a multiple
	//    of 1 MB and goes to the end of the archive. For example, if you have a
	//    3.1 MB archive and you specify a range that starts at 2 MB and ends at
	//    3.1 MB (the end of the archive), then the x-amz-sha256-tree-hash is returned
	//    as a response header.
	Checksum *string `location:"header" locationName:"x-amz-sha256-tree-hash" type:"string"`

	// The range of bytes returned by Amazon Glacier. If only partial output is
	// downloaded, the response provides the range of bytes Amazon Glacier returned.
	// For example, bytes 0-1048575/8388608 returns the first 1 MB from 8 MB.
	ContentRange *string `location:"header" locationName:"Content-Range" type:"string"`

	// The Content-Type depends on whether the job output is an archive or a vault
	// inventory. For archive data, the Content-Type is application/octet-stream.
	// For vault inventory, if you requested CSV format when you initiated the job,
	// the Content-Type is text/csv. Otherwise, by default, vault inventory is returned
	// as JSON, and the Content-Type is application/json.
	ContentType *string `location:"header" locationName:"Content-Type" type:"string"`

	// The HTTP response code for a job output request. The value depends on whether
	// a range was specified in the request.
	Status *int64 `location:"statusCode" locationName:"status" type:"integer"`
}

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

// MarshalFields encodes the AWS API shape using the passed in protocol encoder.
func (s GetJobOutputOutput) MarshalFields(e protocol.FieldEncoder) error {
	if s.AcceptRanges != nil {
		v := *s.AcceptRanges

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "Accept-Ranges", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.ArchiveDescription != nil {
		v := *s.ArchiveDescription

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "x-amz-archive-description", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.Checksum != nil {
		v := *s.Checksum

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "x-amz-sha256-tree-hash", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.ContentRange != nil {
		v := *s.ContentRange

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "Content-Range", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	if s.ContentType != nil {
		v := *s.ContentType

		metadata := protocol.Metadata{}
		e.SetValue(protocol.HeaderTarget, "Content-Type", protocol.QuotedValue{ValueMarshaler: protocol.StringValue(v)}, metadata)
	}
	// Skipping Body Output type's body not valid.
	// ignoring invalid encode state, StatusCode. Status
	return nil
}

const opGetJobOutput = "GetJobOutput"

// GetJobOutputRequest returns a request value for making API operation for
// Amazon Glacier.
//
// This operation downloads the output of the job you initiated using InitiateJob.
// Depending on the job type you specified when you initiated the job, the output
// will be either the content of an archive or a vault inventory.
//
// You can download all the job output or download a portion of the output by
// specifying a byte range. In the case of an archive retrieval job, depending
// on the byte range you specify, Amazon Glacier returns the checksum for the
// portion of the data. You can compute the checksum on the client and verify
// that the values match to ensure the portion you downloaded is the correct
// data.
//
// A job ID will not expire for at least 24 hours after Amazon Glacier completes
// the job. That a byte range. For both archive and inventory retrieval jobs,
// you should verify the downloaded size against the size returned in the headers
// from the Get Job Output response.
//
// For archive retrieval jobs, you should also verify that the size is what
// you expected. If you download a portion of the output, the expected size
// is based on the range of bytes you specified. For example, if you specify
// a range of bytes=0-1048575, you should verify your download size is 1,048,576
// bytes. If you download an entire archive, the expected size is the size of
// the archive when you uploaded it to Amazon Glacier The expected size is also
// returned in the headers from the Get Job Output response.
//
// In the case of an archive retrieval job, depending on the byte range you
// specify, Amazon Glacier returns the checksum for the portion of the data.
// To ensure the portion you downloaded is the correct data, compute the checksum
// on the client, verify that the values match, and verify that the size is
// what you expected.
//
// A job ID does not expire for at least 24 hours after Amazon Glacier completes
// the job. That is, you can download the job output within the 24 hours period
// after Amazon Glacier completes the job.
//
// An AWS account has full permission to perform all operations (actions). However,
// AWS Identity and Access Management (IAM) users don't have any permissions
// by default. You must grant them explicit permission to perform specific actions.
// For more information, see Access Control Using AWS Identity and Access Management
// (IAM) (http://docs.aws.amazon.com/amazonglacier/latest/dev/using-iam-with-amazon-glacier.html).
//
// For conceptual information and the underlying REST API, see Downloading a
// Vault Inventory (http://docs.aws.amazon.com/amazonglacier/latest/dev/vault-inventory.html),
// Downloading an Archive (http://docs.aws.amazon.com/amazonglacier/latest/dev/downloading-an-archive.html),
// and Get Job Output (http://docs.aws.amazon.com/amazonglacier/latest/dev/api-job-output-get.html)
//
//    // Example sending a request using GetJobOutputRequest.
//    req := client.GetJobOutputRequest(params)
//    resp, err := req.Send(context.TODO())
//    if err == nil {
//        fmt.Println(resp)
//    }
func (c *Client) GetJobOutputRequest(input *GetJobOutputInput) GetJobOutputRequest {
	op := &aws.Operation{
		Name:       opGetJobOutput,
		HTTPMethod: "GET",
		HTTPPath:   "/{accountId}/vaults/{vaultName}/jobs/{jobId}/output",
	}

	if input == nil {
		input = &GetJobOutputInput{}
	}

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

// GetJobOutputRequest is the request type for the
// GetJobOutput API operation.
type GetJobOutputRequest struct {
	*aws.Request
	Input *GetJobOutputInput
	Copy  func(*GetJobOutputInput) GetJobOutputRequest
}

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

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

	return resp, nil
}

// GetJobOutputResponse is the response type for the
// GetJobOutput API operation.
type GetJobOutputResponse struct {
	*GetJobOutputOutput

	response *aws.Response
}

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