// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package playmoviespartner provides access to the Google Play Movies Partner API.
//
// For product documentation, see: https://developers.google.com/playmoviespartner/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/playmoviespartner/v1"
//   ...
//   ctx := context.Background()
//   playmoviespartnerService, err := playmoviespartner.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   playmoviespartnerService, err := playmoviespartner.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   playmoviespartnerService, err := playmoviespartner.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package playmoviespartner // import "google.golang.org/api/playmoviespartner/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	htransport "google.golang.org/api/transport/http"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled

const apiId = "playmoviespartner:v1"
const apiName = "playmoviespartner"
const apiVersion = "v1"
const basePath = "https://playmoviespartner.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View the digital assets you publish on Google Play Movies and TV
	PlaymoviesPartnerReadonlyScope = "https://www.googleapis.com/auth/playmovies_partner.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/playmovies_partner.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.Accounts = NewAccountsService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	Accounts *AccountsService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewAccountsService(s *Service) *AccountsService {
	rs := &AccountsService{s: s}
	rs.Avails = NewAccountsAvailsService(s)
	rs.Orders = NewAccountsOrdersService(s)
	rs.StoreInfos = NewAccountsStoreInfosService(s)
	return rs
}

type AccountsService struct {
	s *Service

	Avails *AccountsAvailsService

	Orders *AccountsOrdersService

	StoreInfos *AccountsStoreInfosService
}

func NewAccountsAvailsService(s *Service) *AccountsAvailsService {
	rs := &AccountsAvailsService{s: s}
	return rs
}

type AccountsAvailsService struct {
	s *Service
}

func NewAccountsOrdersService(s *Service) *AccountsOrdersService {
	rs := &AccountsOrdersService{s: s}
	return rs
}

type AccountsOrdersService struct {
	s *Service
}

func NewAccountsStoreInfosService(s *Service) *AccountsStoreInfosService {
	rs := &AccountsStoreInfosService{s: s}
	rs.Country = NewAccountsStoreInfosCountryService(s)
	return rs
}

type AccountsStoreInfosService struct {
	s *Service

	Country *AccountsStoreInfosCountryService
}

func NewAccountsStoreInfosCountryService(s *Service) *AccountsStoreInfosCountryService {
	rs := &AccountsStoreInfosCountryService{s: s}
	return rs
}

type AccountsStoreInfosCountryService struct {
	s *Service
}

// Avail: An Avail describes the Availability Window of a specific Edit
// in a given
// country, which means the period Google is allowed to sell or rent the
// Edit.
//
// Avails are exposed in EMA format Version 1.6b (available
// at
// http://www.movielabs.com/md/avails/)
//
// Studios can see the Avails for the Titles they own.
// Post-production houses cannot see any Avails.
type Avail struct {
	// AltId: Other identifier referring to the Edit, as defined by
	// partner.
	// Example: "GOOGLER_2006"
	AltId string `json:"altId,omitempty"`

	// AvailId: ID internally generated by Google to uniquely identify an
	// Avail.
	// Not part of EMA Specs.
	AvailId string `json:"availId,omitempty"`

	// CaptionExemption: Communicating an exempt category as defined by FCC
	// regulations.
	// It is not required for non-US Avails.
	// Example: "1"
	CaptionExemption string `json:"captionExemption,omitempty"`

	// CaptionIncluded: Communicating if caption file will be delivered.
	CaptionIncluded bool `json:"captionIncluded,omitempty"`

	// ContentId: Title Identifier. This should be the Title Level
	// EIDR.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-5".
	ContentId string `json:"contentId,omitempty"`

	// DisplayName: The name of the studio that owns the Edit referred in
	// the Avail.
	// This is the equivalent of `studio_name` in other resources, but it
	// follows
	// the EMA nomenclature.
	// Example: "Google Films".
	DisplayName string `json:"displayName,omitempty"`

	// EncodeId: Manifestation Identifier. This should be the
	// Manifestation
	// Level EIDR.
	// Example: "10.2340/1489-49A2-3956-4B2D-FE16-7"
	EncodeId string `json:"encodeId,omitempty"`

	// End: End of term in YYYY-MM-DD format in the timezone of the
	// country
	// of the Avail.
	// "Open" if no end date is available.
	// Example: "2019-02-17"
	End string `json:"end,omitempty"`

	// EpisodeAltId: Other identifier referring to the episode, as defined
	// by partner.
	// Only available on TV avails.
	// Example: "rs_googlers_s1_3".
	EpisodeAltId string `json:"episodeAltId,omitempty"`

	// EpisodeNumber: The number assigned to the episode within a
	// season.
	// Only available on TV Avails.
	// Example: "3".
	EpisodeNumber string `json:"episodeNumber,omitempty"`

	// EpisodeTitleInternalAlias: OPTIONAL.TV Only. Title used by involved
	// parties to refer to this episode.
	// Only available on TV Avails.
	// Example: "Coding at Google".
	EpisodeTitleInternalAlias string `json:"episodeTitleInternalAlias,omitempty"`

	// FormatProfile: Indicates the format profile covered by the
	// transaction.
	//
	// Possible values:
	//   "FORMAT_PROFILE_UNSPECIFIED" - Value could not be determined,
	// please contact technical support if
	// it should.
	//   "SD" - Standard-definition format.
	//   "HD" - High-definition format.
	//   "UHD" - 4K UHD.
	FormatProfile string `json:"formatProfile,omitempty"`

	// LicenseType: Type of transaction.
	//
	// Possible values:
	//   "LICENSE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "EST" - Electronic Sell Through - purchase policy for unlimited
	// viewing.
	//   "VOD" - Video On Demand - rental policy for temporary viewing.
	//   "SVOD" - Subscription Video On Demand - used for subscription
	// platforms.
	// Not supported on Google Play.
	//   "POEST" - Pre-order Electronic Sell Through - pre-order purchase
	// only window.
	LicenseType string `json:"licenseType,omitempty"`

	// PphNames: Name of the post-production houses that manage the
	// Avail.
	// Not part of EMA Specs.
	PphNames []string `json:"pphNames,omitempty"`

	// PriceType: Type of pricing that should be applied to this Avail
	// based on how the partner classify them.
	// Example: "Tier", "WSP", "SRP", or "Category".
	PriceType string `json:"priceType,omitempty"`

	// PriceValue: Value to be applied to the pricing type.
	// Example: "4" or "2.99"
	PriceValue string `json:"priceValue,omitempty"`

	// ProductId: Edit Identifier. This should be the Edit Level
	// EIDR.
	// Example: "10.2340/1489-49A2-3956-4B2D-FE16-6"
	ProductId string `json:"productId,omitempty"`

	// RatingReason: Value representing the rating reason.
	// Rating reasons should be formatted as per
	// [EMA ratings spec](http://www.movielabs.com/md/ratings/)
	// and comma-separated for inclusion of multiple reasons.
	// Example: "L, S, V"
	RatingReason string `json:"ratingReason,omitempty"`

	// RatingSystem: Rating system applied to the version of title within
	// territory
	// of Avail.
	// Rating systems should be formatted as per
	// [EMA ratings spec](http://www.movielabs.com/md/ratings/)
	// Example: "MPAA"
	RatingSystem string `json:"ratingSystem,omitempty"`

	// RatingValue: Value representing the rating.
	// Ratings should be formatted as per
	// http://www.movielabs.com/md/ratings/
	// Example: "PG"
	RatingValue string `json:"ratingValue,omitempty"`

	// ReleaseDate: Release date of the Title in earliest released
	// territory.
	// Typically it is just the year, but it is free-form as per EMA
	// spec.
	// Examples: "1979", "Oct 2014"
	ReleaseDate string `json:"releaseDate,omitempty"`

	// SeasonAltId: Other identifier referring to the season, as defined by
	// partner.
	// Only available on TV avails.
	// Example: "rs_googlers_s1".
	SeasonAltId string `json:"seasonAltId,omitempty"`

	// SeasonNumber: The number assigned to the season within a series.
	// Only available on TV Avails.
	// Example: "1".
	SeasonNumber string `json:"seasonNumber,omitempty"`

	// SeasonTitleInternalAlias: Title used by involved parties to refer to
	// this season.
	// Only available on TV Avails.
	// Example: "Googlers, The".
	SeasonTitleInternalAlias string `json:"seasonTitleInternalAlias,omitempty"`

	// SeriesAltId: Other identifier referring to the series, as defined by
	// partner.
	// Only available on TV avails.
	// Example: "rs_googlers".
	SeriesAltId string `json:"seriesAltId,omitempty"`

	// SeriesTitleInternalAlias: Title used by involved parties to refer to
	// this series.
	// Only available on TV Avails.
	// Example: "Googlers, The".
	SeriesTitleInternalAlias string `json:"seriesTitleInternalAlias,omitempty"`

	// Start: Start of term in YYYY-MM-DD format in the timezone of
	// the
	// country of the Avail.
	// Example: "2013-05-14".
	Start string `json:"start,omitempty"`

	// StoreLanguage: Spoken language of the intended audience.
	// Language shall be encoded in accordance with RFC 5646.
	// Example: "fr".
	StoreLanguage string `json:"storeLanguage,omitempty"`

	// SuppressionLiftDate: First date an Edit could be publically announced
	// as becoming
	// available at a specific future date in territory of Avail.
	// *Not* the Avail start date or pre-order start date.
	// Format is YYYY-MM-DD.
	// Only available for pre-orders.
	// Example: "2012-12-10"
	SuppressionLiftDate string `json:"suppressionLiftDate,omitempty"`

	// Territory: ISO 3166-1 alpha-2 country code for the country or
	// territory
	// of this Avail.
	// For Avails, we use Territory in lieu of Country to comply with
	// EMA specifications.
	// But please note that Territory and Country identify the same
	// thing.
	// Example: "US".
	Territory string `json:"territory,omitempty"`

	// TitleInternalAlias: Title used by involved parties to refer to this
	// content.
	// Example: "Googlers, The".
	// Only available on Movie Avails.
	TitleInternalAlias string `json:"titleInternalAlias,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to this
	// Avail, once
	// delivered.
	// Not part of EMA Specs.
	// Example: 'gtry456_xc'
	VideoId string `json:"videoId,omitempty"`

	// WorkType: Work type as enumerated in EMA.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	WorkType string `json:"workType,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AltId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AltId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Avail) MarshalJSON() ([]byte, error) {
	type NoMethod Avail
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListAvailsResponse: Response to the 'ListAvails' method.
type ListAvailsResponse struct {
	// Avails: List of Avails that match the request criteria.
	Avails []*Avail `json:"avails,omitempty"`

	// NextPageToken: See _List methods rules_ for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Avails") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Avails") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListAvailsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListAvailsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListOrdersResponse: Response to the 'ListOrders' method.
type ListOrdersResponse struct {
	// NextPageToken: See _List methods rules_ for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Orders: List of Orders that match the request criteria.
	Orders []*Order `json:"orders,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListOrdersResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListOrdersResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListStoreInfosResponse: Response to the 'ListStoreInfos' method.
type ListStoreInfosResponse struct {
	// NextPageToken: See 'List methods rules' for info about this field.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// StoreInfos: List of StoreInfos that match the request criteria.
	StoreInfos []*StoreInfo `json:"storeInfos,omitempty"`

	// TotalSize: See _List methods rules_ for more information about this
	// field.
	TotalSize int64 `json:"totalSize,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "NextPageToken") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "NextPageToken") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *ListStoreInfosResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListStoreInfosResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// Order: An Order tracks the fulfillment of an Edit when delivered
// using the
// legacy, non-component-based delivery.
//
// Each Order is uniquely identified by an `order_id`, which is
// generated
// by Google.
//
// Externally, Orders can also be identified by partners using its
// `custom_id`
// (when provided).
type Order struct {
	// ApprovedTime: Timestamp when the Order was approved.
	ApprovedTime string `json:"approvedTime,omitempty"`

	// ChannelId: YouTube Channel ID that should be used to fulfill the
	// Order.
	// Example: "UCRG64darCZhb".
	ChannelId string `json:"channelId,omitempty"`

	// ChannelName: YouTube Channel Name that should be used to fulfill the
	// Order.
	// Example: "Google_channel".
	ChannelName string `json:"channelName,omitempty"`

	// Countries: Countries where the Order is available,
	// using the "ISO 3166-1 alpha-2" format (example: "US").
	Countries []string `json:"countries,omitempty"`

	// CustomId: ID that can be used to externally identify an Order.
	// This ID is provided by partners when submitting the Avails.
	// Example: 'GOOGLER_2006'
	CustomId string `json:"customId,omitempty"`

	// EarliestAvailStartTime: Timestamp of the earliest start date of the
	// Avails
	// linked to this Order.
	EarliestAvailStartTime string `json:"earliestAvailStartTime,omitempty"`

	// EpisodeName: Default Episode name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The - Pilot".
	EpisodeName string `json:"episodeName,omitempty"`

	// LegacyPriority: Legacy Order priority, as defined by Google.
	// Example: 'P0'
	LegacyPriority string `json:"legacyPriority,omitempty"`

	// Name: Default Edit name,
	// usually in the language of the country of origin.
	// Example: "Googlers, The".
	Name string `json:"name,omitempty"`

	// NormalizedPriority: A simpler representation of the priority.
	//
	// Possible values:
	//   "NORMALIZED_PRIORITY_UNSPECIFIED" - Value could not be determined,
	// please contact technical support if
	// it should.
	//   "LOW_PRIORITY" - A low-priority asset, typically from a library
	// movie.
	//   "HIGH_PRIORITY" - A high-priority asset, typically from a new
	// release or box office hit.
	NormalizedPriority string `json:"normalizedPriority,omitempty"`

	// OrderId: ID internally generated by Google to uniquely identify an
	// Order.
	// Example: 'abcde12_x'
	OrderId string `json:"orderId,omitempty"`

	// OrderedTime: Timestamp when the Order was created.
	OrderedTime string `json:"orderedTime,omitempty"`

	// PphName: Name of the post-production house that manages the Edit
	// ordered.
	PphName string `json:"pphName,omitempty"`

	// Priority: Order priority, as defined by Google.
	// The higher the value, the higher the priority.
	// Example: 90
	Priority float64 `json:"priority,omitempty"`

	// ReceivedTime: Timestamp when the Order was fulfilled.
	ReceivedTime string `json:"receivedTime,omitempty"`

	// RejectionNote: Field explaining why an Order has been
	// rejected.
	// Example: "Trailer audio is 2ch mono, please re-deliver in stereo".
	RejectionNote string `json:"rejectionNote,omitempty"`

	// SeasonName: Default Season name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The - A Brave New World".
	SeasonName string `json:"seasonName,omitempty"`

	// ShowName: Default Show name,
	// usually in the language of the country of origin.
	// Only available for TV Edits
	// Example: "Googlers, The".
	ShowName string `json:"showName,omitempty"`

	// Status: High-level status of the order.
	//
	// Possible values:
	//   "STATUS_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "STATUS_APPROVED" - Approved by Google.
	//   "STATUS_FAILED" - Waiting for partner to re-deliver the asset after
	// a rejection by Google.
	//   "STATUS_PROCESSING" - Waiting for Google to process the asset.
	//   "STATUS_UNFULFILLED" - Waiting for partner to deliver the asset.
	//   "STATUS_NOT_AVAILABLE" - Used when Status is not available (i.e:
	// Orders for TV Seasons).
	Status string `json:"status,omitempty"`

	// StatusDetail: Detailed status of the order
	//
	// Possible values:
	//   "ORDER_STATUS_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "ORDER_STATUS_QC_APPROVED" - Approved by Google's Quality Control
	// team.
	//   "ORDER_STATUS_QC_REJECTION" - Rejected by Google's Quality Control
	// team, pending partner redelivery.
	//   "ORDER_STATUS_INTERNAL_FIX" - Internal error while processing the
	// Order.
	//   "ORDER_STATUS_OPEN_ORDER" - Waiting for initial delivery from
	// partner.
	//   "ORDER_STATUS_NOT_AVAILABLE" - Used on Orders that do not have
	// Status, like TV Seasons.
	//   "ORDER_STATUS_AWAITING_REDELIVERY" - Waiting for re-delivery from
	// partner.
	//   "ORDER_STATUS_READY_FOR_QC" - Asset was delivered by partner, but
	// is being reviewed by Google's
	// Quality Control team.
	//   "ORDER_STATUS_FILE_PROCESSING" - Waiting for Google to process the
	// asset.
	StatusDetail string `json:"statusDetail,omitempty"`

	// StudioName: Name of the studio that owns the Edit ordered.
	StudioName string `json:"studioName,omitempty"`

	// Type: Type of the Edit linked to the Order.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	Type string `json:"type,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to this
	// Order, once
	// delivered.
	// Example: 'gtry456_xc'.
	VideoId string `json:"videoId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ApprovedTime") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "ApprovedTime") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *Order) MarshalJSON() ([]byte, error) {
	type NoMethod Order
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *Order) UnmarshalJSON(data []byte) error {
	type NoMethod Order
	var s1 struct {
		Priority gensupport.JSONFloat64 `json:"priority"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Priority = float64(s1.Priority)
	return nil
}

// StoreInfo: Information about a playable sequence (video) associated
// with an Edit
// and available at the Google Play Store.
//
// Internally, each StoreInfo is uniquely identified by a `video_id`
// and `country`.
//
// Externally, Title-level EIDR or Edit-level EIDR, if provided,
// can also be used to identify a specific title or edit in a country.
type StoreInfo struct {
	// AudioTracks: Audio tracks available for this Edit.
	AudioTracks []string `json:"audioTracks,omitempty"`

	// Country: Country where Edit is available in ISO 3166-1 alpha-2
	// country
	// code.
	// Example: "US".
	Country string `json:"country,omitempty"`

	// EditLevelEidr: Edit-level EIDR ID.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-6".
	EditLevelEidr string `json:"editLevelEidr,omitempty"`

	// EpisodeNumber: The number assigned to the episode within a
	// season.
	// Only available on TV Edits.
	// Example: "1".
	EpisodeNumber string `json:"episodeNumber,omitempty"`

	// HasAudio51: Whether the Edit has a 5.1 channel audio track.
	HasAudio51 bool `json:"hasAudio51,omitempty"`

	// HasEstOffer: Whether the Edit has a EST offer.
	HasEstOffer bool `json:"hasEstOffer,omitempty"`

	// HasHdOffer: Whether the Edit has a HD offer.
	HasHdOffer bool `json:"hasHdOffer,omitempty"`

	// HasInfoCards: Whether the Edit has info cards.
	HasInfoCards bool `json:"hasInfoCards,omitempty"`

	// HasSdOffer: Whether the Edit has a SD offer.
	HasSdOffer bool `json:"hasSdOffer,omitempty"`

	// HasVodOffer: Whether the Edit has a VOD offer.
	HasVodOffer bool `json:"hasVodOffer,omitempty"`

	// LiveTime: Timestamp when the Edit went live on the Store.
	LiveTime string `json:"liveTime,omitempty"`

	// Mid: Knowledge Graph ID associated to this Edit, if available.
	// This ID links the Edit to its knowledge entity, externally
	// accessible
	// at http://freebase.com.
	// In the absense of Title EIDR or Edit EIDR, this ID helps link
	// together
	// multiple Edits across countries.
	// Example: '/m/0ffx29'
	Mid string `json:"mid,omitempty"`

	// Name: Default Edit name, usually in the language of the country
	// of
	// origin.
	// Example: "Googlers, The".
	Name string `json:"name,omitempty"`

	// PphNames: Name of the post-production houses that manage the Edit.
	PphNames []string `json:"pphNames,omitempty"`

	// SeasonId: Google-generated ID identifying the season linked to the
	// Edit.
	// Only available for TV Edits.
	// Example: 'ster23ex'
	SeasonId string `json:"seasonId,omitempty"`

	// SeasonName: Default Season name, usually in the language of the
	// country of
	// origin.
	// Only available for TV Edits
	// Example: "Googlers, The - A Brave New World".
	SeasonName string `json:"seasonName,omitempty"`

	// SeasonNumber: The number assigned to the season within a show.
	// Only available on TV Edits.
	// Example: "1".
	SeasonNumber string `json:"seasonNumber,omitempty"`

	// ShowId: Google-generated ID identifying the show linked to the
	// Edit.
	// Only available for TV Edits.
	// Example: 'et2hsue_x'
	ShowId string `json:"showId,omitempty"`

	// ShowName: Default Show name, usually in the language of the country
	// of
	// origin.
	// Only available for TV Edits
	// Example: "Googlers, The".
	ShowName string `json:"showName,omitempty"`

	// StudioName: Name of the studio that owns the Edit ordered.
	StudioName string `json:"studioName,omitempty"`

	// Subtitles: Subtitles available for this Edit.
	Subtitles []string `json:"subtitles,omitempty"`

	// TitleLevelEidr: Title-level EIDR ID.
	// Example: "10.5240/1489-49A2-3956-4B2D-FE16-5".
	TitleLevelEidr string `json:"titleLevelEidr,omitempty"`

	// TrailerId: Google-generated ID identifying the trailer linked to the
	// Edit.
	// Example: 'bhd_4e_cx'
	TrailerId string `json:"trailerId,omitempty"`

	// Type: Edit type, like Movie, Episode or Season.
	//
	// Possible values:
	//   "TITLE_TYPE_UNSPECIFIED" - Value could not be determined, please
	// contact technical support if
	// it should.
	//   "MOVIE" - A movie picture.
	//   "SEASON" - A season of a TV show.
	//   "EPISODE" - An episode of a TV show.
	//   "BUNDLE" - A collection of movies, i.e. "Googlers 1 and Googlers,
	// the return"
	Type string `json:"type,omitempty"`

	// VideoId: Google-generated ID identifying the video linked to the
	// Edit.
	// Example: 'gtry456_xc'
	VideoId string `json:"videoId,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AudioTracks") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "AudioTracks") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *StoreInfo) MarshalJSON() ([]byte, error) {
	type NoMethod StoreInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "playmoviespartner.accounts.avails.get":

type AccountsAvailsGetCall struct {
	s            *Service
	accountId    string
	availId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get an Avail given its avail group id and avail id.
func (r *AccountsAvailsService) Get(accountId string, availId string) *AccountsAvailsGetCall {
	c := &AccountsAvailsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.availId = availId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsAvailsGetCall) Fields(s ...googleapi.Field) *AccountsAvailsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsAvailsGetCall) IfNoneMatch(entityTag string) *AccountsAvailsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsAvailsGetCall) Context(ctx context.Context) *AccountsAvailsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsAvailsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsAvailsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/avails/{availId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"availId":   c.availId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.avails.get" call.
// Exactly one of *Avail or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Avail.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsAvailsGetCall) Do(opts ...googleapi.CallOption) (*Avail, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Avail{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get an Avail given its avail group id and avail id.",
	//   "flatPath": "v1/accounts/{accountId}/avails/{availId}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.avails.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "availId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "availId": {
	//       "description": "REQUIRED. Avail ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/avails/{availId}",
	//   "response": {
	//     "$ref": "Avail"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// method id "playmoviespartner.accounts.avails.list":

type AccountsAvailsListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List Avails owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsAvailsService) List(accountId string) *AccountsAvailsListCall {
	c := &AccountsAvailsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// AltId sets the optional parameter "altId": Filter Avails that match a
// case-insensitive, partner-specific custom id.
// NOTE: this field is deprecated and will be removed on V2;
// `alt_ids`
// should be used instead.
func (c *AccountsAvailsListCall) AltId(altId string) *AccountsAvailsListCall {
	c.urlParams_.Set("altId", altId)
	return c
}

// AltIds sets the optional parameter "altIds": Filter Avails that match
// (case-insensitive) any of the given partner-specific custom ids.
func (c *AccountsAvailsListCall) AltIds(altIds ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("altIds", append([]string{}, altIds...))
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PageSize(pageSize int64) *AccountsAvailsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PageToken(pageToken string) *AccountsAvailsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsAvailsListCall) PphNames(pphNames ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsAvailsListCall) StudioNames(studioNames ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// Territories sets the optional parameter "territories": Filter Avails
// that match (case-insensitive) any of the given country codes,
// using the "ISO 3166-1 alpha-2" format (examples: "US", "us", "Us").
func (c *AccountsAvailsListCall) Territories(territories ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("territories", append([]string{}, territories...))
	return c
}

// Title sets the optional parameter "title": Filter that matches Avails
// with a `title_internal_alias`,
// `series_title_internal_alias`, `season_title_internal_alias`,
// or `episode_title_internal_alias` that contains the
// given
// case-insensitive title.
func (c *AccountsAvailsListCall) Title(title string) *AccountsAvailsListCall {
	c.urlParams_.Set("title", title)
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter Avails that
// match any of the given `video_id`s.
func (c *AccountsAvailsListCall) VideoIds(videoIds ...string) *AccountsAvailsListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsAvailsListCall) Fields(s ...googleapi.Field) *AccountsAvailsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsAvailsListCall) IfNoneMatch(entityTag string) *AccountsAvailsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsAvailsListCall) Context(ctx context.Context) *AccountsAvailsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsAvailsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsAvailsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/avails")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.avails.list" call.
// Exactly one of *ListAvailsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListAvailsResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsAvailsListCall) Do(opts ...googleapi.CallOption) (*ListAvailsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListAvailsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List Avails owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/avails",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.avails.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "altId": {
	//       "description": "Filter Avails that match a case-insensitive, partner-specific custom id.\nNOTE: this field is deprecated and will be removed on V2; `alt_ids`\nshould be used instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "altIds": {
	//       "description": "Filter Avails that match (case-insensitive) any of the given partner-specific custom ids.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "territories": {
	//       "description": "Filter Avails that match (case-insensitive) any of the given country codes,\nusing the \"ISO 3166-1 alpha-2\" format (examples: \"US\", \"us\", \"Us\").",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "title": {
	//       "description": "Filter that matches Avails with a `title_internal_alias`,\n`series_title_internal_alias`, `season_title_internal_alias`,\nor `episode_title_internal_alias` that contains the given\ncase-insensitive title.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter Avails that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/avails",
	//   "response": {
	//     "$ref": "ListAvailsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsAvailsListCall) Pages(ctx context.Context, f func(*ListAvailsResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.orders.get":

type AccountsOrdersGetCall struct {
	s            *Service
	accountId    string
	orderId      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get an Order given its id.
//
// See _Authentication and Authorization rules_ and
// _Get methods rules_ for more information about this method.
func (r *AccountsOrdersService) Get(accountId string, orderId string) *AccountsOrdersGetCall {
	c := &AccountsOrdersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.orderId = orderId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsOrdersGetCall) Fields(s ...googleapi.Field) *AccountsOrdersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsOrdersGetCall) IfNoneMatch(entityTag string) *AccountsOrdersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsOrdersGetCall) Context(ctx context.Context) *AccountsOrdersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsOrdersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsOrdersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/orders/{orderId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"orderId":   c.orderId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.orders.get" call.
// Exactly one of *Order or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Order.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsOrdersGetCall) Do(opts ...googleapi.CallOption) (*Order, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Order{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get an Order given its id.\n\nSee _Authentication and Authorization rules_ and\n_Get methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/orders/{orderId}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.orders.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "orderId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "orderId": {
	//       "description": "REQUIRED. Order ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/orders/{orderId}",
	//   "response": {
	//     "$ref": "Order"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// method id "playmoviespartner.accounts.orders.list":

type AccountsOrdersListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List Orders owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsOrdersService) List(accountId string) *AccountsOrdersListCall {
	c := &AccountsOrdersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// CustomId sets the optional parameter "customId": Filter Orders that
// match a case-insensitive, partner-specific custom id.
func (c *AccountsOrdersListCall) CustomId(customId string) *AccountsOrdersListCall {
	c.urlParams_.Set("customId", customId)
	return c
}

// Name sets the optional parameter "name": Filter that matches Orders
// with a `name`, `show`, `season` or `episode`
// that contains the given case-insensitive name.
func (c *AccountsOrdersListCall) Name(name string) *AccountsOrdersListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PageSize(pageSize int64) *AccountsOrdersListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PageToken(pageToken string) *AccountsOrdersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsOrdersListCall) PphNames(pphNames ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// Status sets the optional parameter "status": Filter Orders that match
// one of the given status.
//
// Possible values:
//   "STATUS_UNSPECIFIED"
//   "STATUS_APPROVED"
//   "STATUS_FAILED"
//   "STATUS_PROCESSING"
//   "STATUS_UNFULFILLED"
//   "STATUS_NOT_AVAILABLE"
func (c *AccountsOrdersListCall) Status(status ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("status", append([]string{}, status...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsOrdersListCall) StudioNames(studioNames ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter Orders that
// match any of the given `video_id`s.
func (c *AccountsOrdersListCall) VideoIds(videoIds ...string) *AccountsOrdersListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsOrdersListCall) Fields(s ...googleapi.Field) *AccountsOrdersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsOrdersListCall) IfNoneMatch(entityTag string) *AccountsOrdersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsOrdersListCall) Context(ctx context.Context) *AccountsOrdersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsOrdersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsOrdersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/orders")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.orders.list" call.
// Exactly one of *ListOrdersResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListOrdersResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsOrdersListCall) Do(opts ...googleapi.CallOption) (*ListOrdersResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListOrdersResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List Orders owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/orders",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.orders.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "customId": {
	//       "description": "Filter Orders that match a case-insensitive, partner-specific custom id.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Filter that matches Orders with a `name`, `show`, `season` or `episode`\nthat contains the given case-insensitive name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Filter Orders that match one of the given status.",
	//       "enum": [
	//         "STATUS_UNSPECIFIED",
	//         "STATUS_APPROVED",
	//         "STATUS_FAILED",
	//         "STATUS_PROCESSING",
	//         "STATUS_UNFULFILLED",
	//         "STATUS_NOT_AVAILABLE"
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter Orders that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/orders",
	//   "response": {
	//     "$ref": "ListOrdersResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsOrdersListCall) Pages(ctx context.Context, f func(*ListOrdersResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.storeInfos.list":

type AccountsStoreInfosListCall struct {
	s            *Service
	accountId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: List StoreInfos owned or managed by the partner.
//
// See _Authentication and Authorization rules_ and
// _List methods rules_ for more information about this method.
func (r *AccountsStoreInfosService) List(accountId string) *AccountsStoreInfosListCall {
	c := &AccountsStoreInfosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	return c
}

// Countries sets the optional parameter "countries": Filter StoreInfos
// that match (case-insensitive) any of the given country
// codes, using the "ISO 3166-1 alpha-2" format (examples: "US", "us",
// "Us").
func (c *AccountsStoreInfosListCall) Countries(countries ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("countries", append([]string{}, countries...))
	return c
}

// Mids sets the optional parameter "mids": Filter StoreInfos that match
// any of the given `mid`s.
func (c *AccountsStoreInfosListCall) Mids(mids ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("mids", append([]string{}, mids...))
	return c
}

// Name sets the optional parameter "name": Filter that matches
// StoreInfos with a `name` or `show_name`
// that contains the given case-insensitive name.
func (c *AccountsStoreInfosListCall) Name(name string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageSize sets the optional parameter "pageSize": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PageSize(pageSize int64) *AccountsStoreInfosListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PageToken(pageToken string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PphNames sets the optional parameter "pphNames": See _List methods
// rules_ for info about this field.
func (c *AccountsStoreInfosListCall) PphNames(pphNames ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("pphNames", append([]string{}, pphNames...))
	return c
}

// SeasonIds sets the optional parameter "seasonIds": Filter StoreInfos
// that match any of the given `season_id`s.
func (c *AccountsStoreInfosListCall) SeasonIds(seasonIds ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("seasonIds", append([]string{}, seasonIds...))
	return c
}

// StudioNames sets the optional parameter "studioNames": See _List
// methods rules_ for info about this field.
func (c *AccountsStoreInfosListCall) StudioNames(studioNames ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("studioNames", append([]string{}, studioNames...))
	return c
}

// VideoId sets the optional parameter "videoId": Filter StoreInfos that
// match a given `video_id`.
// NOTE: this field is deprecated and will be removed on V2;
// `video_ids`
// should be used instead.
func (c *AccountsStoreInfosListCall) VideoId(videoId string) *AccountsStoreInfosListCall {
	c.urlParams_.Set("videoId", videoId)
	return c
}

// VideoIds sets the optional parameter "videoIds": Filter StoreInfos
// that match any of the given `video_id`s.
func (c *AccountsStoreInfosListCall) VideoIds(videoIds ...string) *AccountsStoreInfosListCall {
	c.urlParams_.SetMulti("videoIds", append([]string{}, videoIds...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsStoreInfosListCall) Fields(s ...googleapi.Field) *AccountsStoreInfosListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsStoreInfosListCall) IfNoneMatch(entityTag string) *AccountsStoreInfosListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsStoreInfosListCall) Context(ctx context.Context) *AccountsStoreInfosListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsStoreInfosListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsStoreInfosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/storeInfos")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.storeInfos.list" call.
// Exactly one of *ListStoreInfosResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListStoreInfosResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsStoreInfosListCall) Do(opts ...googleapi.CallOption) (*ListStoreInfosResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ListStoreInfosResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "List StoreInfos owned or managed by the partner.\n\nSee _Authentication and Authorization rules_ and\n_List methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/storeInfos",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.storeInfos.list",
	//   "parameterOrder": [
	//     "accountId"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "countries": {
	//       "description": "Filter StoreInfos that match (case-insensitive) any of the given country\ncodes, using the \"ISO 3166-1 alpha-2\" format (examples: \"US\", \"us\", \"Us\").",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "mids": {
	//       "description": "Filter StoreInfos that match any of the given `mid`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "name": {
	//       "description": "Filter that matches StoreInfos with a `name` or `show_name`\nthat contains the given case-insensitive name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageSize": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pphNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "seasonIds": {
	//       "description": "Filter StoreInfos that match any of the given `season_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "studioNames": {
	//       "description": "See _List methods rules_ for info about this field.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "Filter StoreInfos that match a given `video_id`.\nNOTE: this field is deprecated and will be removed on V2; `video_ids`\nshould be used instead.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "videoIds": {
	//       "description": "Filter StoreInfos that match any of the given `video_id`s.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/storeInfos",
	//   "response": {
	//     "$ref": "ListStoreInfosResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsStoreInfosListCall) Pages(ctx context.Context, f func(*ListStoreInfosResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "playmoviespartner.accounts.storeInfos.country.get":

type AccountsStoreInfosCountryGetCall struct {
	s            *Service
	accountId    string
	videoId      string
	country      string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a StoreInfo given its video id and country.
//
// See _Authentication and Authorization rules_ and
// _Get methods rules_ for more information about this method.
func (r *AccountsStoreInfosCountryService) Get(accountId string, videoId string, country string) *AccountsStoreInfosCountryGetCall {
	c := &AccountsStoreInfosCountryGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.accountId = accountId
	c.videoId = videoId
	c.country = country
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsStoreInfosCountryGetCall) Fields(s ...googleapi.Field) *AccountsStoreInfosCountryGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsStoreInfosCountryGetCall) IfNoneMatch(entityTag string) *AccountsStoreInfosCountryGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsStoreInfosCountryGetCall) Context(ctx context.Context) *AccountsStoreInfosCountryGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsStoreInfosCountryGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsStoreInfosCountryGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"accountId": c.accountId,
		"videoId":   c.videoId,
		"country":   c.country,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "playmoviespartner.accounts.storeInfos.country.get" call.
// Exactly one of *StoreInfo or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *StoreInfo.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AccountsStoreInfosCountryGetCall) Do(opts ...googleapi.CallOption) (*StoreInfo, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &StoreInfo{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get a StoreInfo given its video id and country.\n\nSee _Authentication and Authorization rules_ and\n_Get methods rules_ for more information about this method.",
	//   "flatPath": "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}",
	//   "httpMethod": "GET",
	//   "id": "playmoviespartner.accounts.storeInfos.country.get",
	//   "parameterOrder": [
	//     "accountId",
	//     "videoId",
	//     "country"
	//   ],
	//   "parameters": {
	//     "accountId": {
	//       "description": "REQUIRED. See _General rules_ for more information about this field.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "country": {
	//       "description": "REQUIRED. Edit country.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "videoId": {
	//       "description": "REQUIRED. Video ID.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts/{accountId}/storeInfos/{videoId}/country/{country}",
	//   "response": {
	//     "$ref": "StoreInfo"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/playmovies_partner.readonly"
	//   ]
	// }

}
