// 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 gmailpostmastertools provides access to the Gmail Postmaster Tools API.
//
// For product documentation, see: https://developers.google.com/gmail/postmaster
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/gmailpostmastertools/v1beta1"
//   ...
//   ctx := context.Background()
//   gmailpostmastertoolsService, err := gmailpostmastertools.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:
//
//   gmailpostmastertoolsService, err := gmailpostmastertools.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, ...)
//   gmailpostmastertoolsService, err := gmailpostmastertools.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package gmailpostmastertools // import "google.golang.org/api/gmailpostmastertools/v1beta1"

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"
	internaloption "google.golang.org/api/option/internaloption"
	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
var _ = internaloption.WithDefaultEndpoint

const apiId = "gmailpostmastertools:v1beta1"
const apiName = "gmailpostmastertools"
const apiVersion = "v1beta1"
const basePath = "https://gmailpostmastertools.googleapis.com/"
const mtlsBasePath = "https://gmailpostmastertools.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See email traffic metrics for the domains you have registered in
	// Gmail Postmaster Tools
	PostmasterReadonlyScope = "https://www.googleapis.com/auth/postmaster.readonly"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/postmaster.readonly",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	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.Domains = NewDomainsService(s)
	return s, nil
}

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

	Domains *DomainsService
}

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

func NewDomainsService(s *Service) *DomainsService {
	rs := &DomainsService{s: s}
	rs.TrafficStats = NewDomainsTrafficStatsService(s)
	return rs
}

type DomainsService struct {
	s *Service

	TrafficStats *DomainsTrafficStatsService
}

func NewDomainsTrafficStatsService(s *Service) *DomainsTrafficStatsService {
	rs := &DomainsTrafficStatsService{s: s}
	return rs
}

type DomainsTrafficStatsService struct {
	s *Service
}

// DeliveryError: Metric on a particular delivery error type.
type DeliveryError struct {
	// ErrorClass: The class of delivery error.
	//
	// Possible values:
	//   "DELIVERY_ERROR_CLASS_UNSPECIFIED" - The default value which should
	// never be used explicitly.
	//   "PERMANENT_ERROR" - Delivery of message has been rejected.
	//   "TEMPORARY_ERROR" - Temporary failure of message delivery to the
	// recipient.
	ErrorClass string `json:"errorClass,omitempty"`

	// ErrorRatio: The ratio of messages where the error occurred vs all
	// authenticated traffic.
	ErrorRatio float64 `json:"errorRatio,omitempty"`

	// ErrorType: The type of delivery error.
	//
	// Possible values:
	//   "DELIVERY_ERROR_TYPE_UNSPECIFIED" - The default value which should
	// never be used explicitly.
	//   "RATE_LIMIT_EXCEEDED" - The Domain or IP is sending traffic at a
	// suspiciously high rate, due to which temporary rate limits have been
	// imposed. The limit will be lifted when Gmail is confident enough of
	// the nature of the traffic.
	//   "SUSPECTED_SPAM" - The traffic is suspected to be spam, by Gmail,
	// for various reasons.
	//   "CONTENT_SPAMMY" - The traffic is suspected to be spammy, specific
	// to the content.
	//   "BAD_ATTACHMENT" - Traffic contains attachments not supported by
	// Gmail.
	//   "BAD_DMARC_POLICY" - The sender domain has set up a DMARC rejection
	// policy.
	//   "LOW_IP_REPUTATION" - The IP reputation of the sending IP is very
	// low.
	//   "LOW_DOMAIN_REPUTATION" - The Domain reputation of the sending
	// domain is very low.
	//   "IP_IN_RBL" - The IP is listed in one or more public [Real-time
	// Blackhole Lists](http://en.wikipedia.org/wiki/DNSBL). Work with the
	// RBL to get your IP delisted.
	//   "DOMAIN_IN_RBL" - The Domain is listed in one or more public
	// [Real-time Blackhole Lists](http://en.wikipedia.org/wiki/DNSBL). Work
	// with the RBL to get your domain delisted.
	//   "BAD_PTR_RECORD" - The sending IP is missing a [PTR
	// record](https://support.google.com/domains/answer/3251147#ptr).
	ErrorType string `json:"errorType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ErrorClass") 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. "ErrorClass") 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 *DeliveryError) MarshalJSON() ([]byte, error) {
	type NoMethod DeliveryError
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// Domain: A registered domain resource in the Postmaster API.
type Domain struct {
	// CreateTime: Timestamp when the user registered this domain. Assigned
	// by the server.
	CreateTime string `json:"createTime,omitempty"`

	// Name: The resource name of the Domain. Domain names have the form
	// `domains/{domain_name}`, where domain_name is the fully qualified
	// domain name (i.e., mymail.mydomain.com).
	Name string `json:"name,omitempty"`

	// Permission: User’s permission for this domain. Assigned by the
	// server.
	//
	// Possible values:
	//   "PERMISSION_UNSPECIFIED" - The default value and should never be
	// used explicitly.
	//   "OWNER" - User has read access to the domain and can share access
	// with others.
	//   "READER" - User has read access to the domain.
	//   "NONE" - User doesn't have permission to access information about
	// the domain. User did not verify ownership of domain nor was access
	// granted by other domain owners.
	Permission string `json:"permission,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CreateTime") 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. "CreateTime") 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 *Domain) MarshalJSON() ([]byte, error) {
	type NoMethod Domain
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// FeedbackLoop: [Feedback
// loop](https://support.google.com/mail/answer/6254652) identifier
// information.
type FeedbackLoop struct {
	// Id: Feedback loop identifier that uniquely identifies individual
	// campaigns.
	Id string `json:"id,omitempty"`

	// SpamRatio: The ratio of user marked spam messages with the identifier
	// vs the total number of inboxed messages with that identifier.
	SpamRatio float64 `json:"spamRatio,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") 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. "Id") 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 *FeedbackLoop) MarshalJSON() ([]byte, error) {
	type NoMethod FeedbackLoop
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// IpReputation: IP Reputation information for a set of IPs in a
// specific reputation category.
type IpReputation struct {
	// NumIps: Total number of unique IPs in this reputation category. This
	// metric only pertains to traffic that passed
	// [SPF](http://www.openspf.org/) or [DKIM](http://www.dkim.org/).
	NumIps int64 `json:"numIps,omitempty,string"`

	// Reputation: The reputation category this IP reputation represents.
	//
	// Possible values:
	//   "REPUTATION_CATEGORY_UNSPECIFIED" - The default value which should
	// never be used explicitly. This represents the state where no
	// reputation information is available.
	//   "HIGH" - Has a good track record of a very low spam rate, and
	// complies with Gmail's sender guidelines. Mail will rarely be marked
	// by the spam filter.
	//   "MEDIUM" - Known to send good mail, but is prone to sending a low
	// volume of spam intermittently. Most of the email from this entity
	// will have a fair deliverability rate, except when there is a notable
	// increase in spam levels.
	//   "LOW" - Known to send a considerable volume of spam regularly, and
	// mail from this sender will likely be marked as spam.
	//   "BAD" - History of sending an enormously high volume of spam. Mail
	// coming from this entity will almost always be rejected at SMTP level
	// or marked as spam.
	Reputation string `json:"reputation,omitempty"`

	// SampleIps: A sample of IPs in this reputation category.
	SampleIps []string `json:"sampleIps,omitempty"`

	// ForceSendFields is a list of field names (e.g. "NumIps") 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. "NumIps") 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 *IpReputation) MarshalJSON() ([]byte, error) {
	type NoMethod IpReputation
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListDomainsResponse: Response message for ListDomains.
type ListDomainsResponse struct {
	// Domains: The list of domains.
	Domains []*Domain `json:"domains,omitempty"`

	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Domains") 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. "Domains") 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 *ListDomainsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListDomainsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// ListTrafficStatsResponse: Response message for ListTrafficStats.
type ListTrafficStatsResponse struct {
	// NextPageToken: Token to retrieve the next page of results, or empty
	// if there are no more results in the list.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// TrafficStats: The list of TrafficStats.
	TrafficStats []*TrafficStats `json:"trafficStats,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 *ListTrafficStatsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListTrafficStatsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// TrafficStats: Email traffic statistics pertaining to a specific date.
type TrafficStats struct {
	// DeliveryErrors: Delivery errors for the domain. This metric only
	// pertains to traffic that passed [SPF](http://www.openspf.org/) or
	// [DKIM](http://www.dkim.org/).
	DeliveryErrors []*DeliveryError `json:"deliveryErrors,omitempty"`

	// DkimSuccessRatio: The ratio of mail that successfully authenticated
	// with DKIM vs. all mail that attempted to authenticate with
	// [DKIM](http://www.dkim.org/). Spoofed mail is excluded.
	DkimSuccessRatio float64 `json:"dkimSuccessRatio,omitempty"`

	// DmarcSuccessRatio: The ratio of mail that passed
	// [DMARC](https://dmarc.org/) alignment checks vs all mail received
	// from the domain that successfully authenticated with either of
	// [SPF](http://www.openspf.org/) or [DKIM](http://www.dkim.org/).
	DmarcSuccessRatio float64 `json:"dmarcSuccessRatio,omitempty"`

	// DomainReputation: Reputation of the domain.
	//
	// Possible values:
	//   "REPUTATION_CATEGORY_UNSPECIFIED" - The default value which should
	// never be used explicitly. This represents the state where no
	// reputation information is available.
	//   "HIGH" - Has a good track record of a very low spam rate, and
	// complies with Gmail's sender guidelines. Mail will rarely be marked
	// by the spam filter.
	//   "MEDIUM" - Known to send good mail, but is prone to sending a low
	// volume of spam intermittently. Most of the email from this entity
	// will have a fair deliverability rate, except when there is a notable
	// increase in spam levels.
	//   "LOW" - Known to send a considerable volume of spam regularly, and
	// mail from this sender will likely be marked as spam.
	//   "BAD" - History of sending an enormously high volume of spam. Mail
	// coming from this entity will almost always be rejected at SMTP level
	// or marked as spam.
	DomainReputation string `json:"domainReputation,omitempty"`

	// InboundEncryptionRatio: The ratio of incoming mail (to Gmail), that
	// passed secure transport (TLS) vs all mail received from that domain.
	// This metric only pertains to traffic that passed
	// [SPF](http://www.openspf.org/) or [DKIM](http://www.dkim.org/).
	InboundEncryptionRatio float64 `json:"inboundEncryptionRatio,omitempty"`

	// IpReputations: Reputation information pertaining to the IP addresses
	// of the email servers for the domain. There is exactly one entry for
	// each reputation category except REPUTATION_CATEGORY_UNSPECIFIED.
	IpReputations []*IpReputation `json:"ipReputations,omitempty"`

	// Name: The resource name of the traffic statistics. Traffic statistic
	// names have the form `domains/{domain}/trafficStats/{date}`, where
	// domain_name is the fully qualified domain name (i.e.,
	// mymail.mydomain.com) of the domain this traffic statistics pertains
	// to and date is the date in yyyymmdd format that these statistics
	// corresponds to. For example:
	// domains/mymail.mydomain.com/trafficStats/20160807
	Name string `json:"name,omitempty"`

	// OutboundEncryptionRatio: The ratio of outgoing mail (from Gmail) that
	// was accepted over secure transport (TLS).
	OutboundEncryptionRatio float64 `json:"outboundEncryptionRatio,omitempty"`

	// SpammyFeedbackLoops: Spammy [Feedback loop identifiers]
	// (https://support.google.com/mail/answer/6254652) with their
	// individual spam rates. This metric only pertains to traffic that is
	// authenticated by [DKIM](http://www.dkim.org/).
	SpammyFeedbackLoops []*FeedbackLoop `json:"spammyFeedbackLoops,omitempty"`

	// SpfSuccessRatio: The ratio of mail that successfully authenticated
	// with SPF vs. all mail that attempted to authenticate with
	// [SPF](http://www.openspf.org/). Spoofed mail is excluded.
	SpfSuccessRatio float64 `json:"spfSuccessRatio,omitempty"`

	// UserReportedSpamRatio: The ratio of user-report spam vs. email that
	// was sent to the inbox. This metric only pertains to emails
	// authenticated by [DKIM](http://www.dkim.org/).
	UserReportedSpamRatio float64 `json:"userReportedSpamRatio,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "DeliveryErrors") 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. "DeliveryErrors") 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 *TrafficStats) MarshalJSON() ([]byte, error) {
	type NoMethod TrafficStats
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *TrafficStats) UnmarshalJSON(data []byte) error {
	type NoMethod TrafficStats
	var s1 struct {
		DkimSuccessRatio        gensupport.JSONFloat64 `json:"dkimSuccessRatio"`
		DmarcSuccessRatio       gensupport.JSONFloat64 `json:"dmarcSuccessRatio"`
		InboundEncryptionRatio  gensupport.JSONFloat64 `json:"inboundEncryptionRatio"`
		OutboundEncryptionRatio gensupport.JSONFloat64 `json:"outboundEncryptionRatio"`
		SpfSuccessRatio         gensupport.JSONFloat64 `json:"spfSuccessRatio"`
		UserReportedSpamRatio   gensupport.JSONFloat64 `json:"userReportedSpamRatio"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.DkimSuccessRatio = float64(s1.DkimSuccessRatio)
	s.DmarcSuccessRatio = float64(s1.DmarcSuccessRatio)
	s.InboundEncryptionRatio = float64(s1.InboundEncryptionRatio)
	s.OutboundEncryptionRatio = float64(s1.OutboundEncryptionRatio)
	s.SpfSuccessRatio = float64(s1.SpfSuccessRatio)
	s.UserReportedSpamRatio = float64(s1.UserReportedSpamRatio)
	return nil
}

// method id "gmailpostmastertools.domains.get":

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

// Get: Gets a specific domain registered by the client. Returns
// NOT_FOUND if the domain does not exist.
func (r *DomainsService) Get(name string) *DomainsGetCall {
	c := &DomainsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *DomainsGetCall) Fields(s ...googleapi.Field) *DomainsGetCall {
	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 *DomainsGetCall) IfNoneMatch(entityTag string) *DomainsGetCall {
	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 *DomainsGetCall) Context(ctx context.Context) *DomainsGetCall {
	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 *DomainsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DomainsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200901")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "gmailpostmastertools.domains.get" call.
// Exactly one of *Domain or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Domain.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 *DomainsGetCall) Do(opts ...googleapi.CallOption) (*Domain, 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 := &Domain{
		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": "Gets a specific domain registered by the client. Returns NOT_FOUND if the domain does not exist.",
	//   "flatPath": "v1beta1/domains/{domainsId}",
	//   "httpMethod": "GET",
	//   "id": "gmailpostmastertools.domains.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The resource name of the domain. It should have the form `domains/{domain_name}`, where domain_name is the fully qualified domain name.",
	//       "location": "path",
	//       "pattern": "^domains/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "Domain"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/postmaster.readonly"
	//   ]
	// }

}

// method id "gmailpostmastertools.domains.list":

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

// List: Lists the domains that have been registered by the client. The
// order of domains in the response is unspecified and
// non-deterministic. Newly created domains will not necessarily be
// added to the end of this list.
func (r *DomainsService) List() *DomainsListCall {
	c := &DomainsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Server may return fewer domains than requested. If unspecified,
// server will pick an appropriate default.
func (c *DomainsListCall) PageSize(pageSize int64) *DomainsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
// This is the value of ListDomainsResponse.next_page_token returned
// from the previous call to `ListDomains` method.
func (c *DomainsListCall) PageToken(pageToken string) *DomainsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	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 *DomainsListCall) Fields(s ...googleapi.Field) *DomainsListCall {
	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 *DomainsListCall) IfNoneMatch(entityTag string) *DomainsListCall {
	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 *DomainsListCall) Context(ctx context.Context) *DomainsListCall {
	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 *DomainsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DomainsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200901")
	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, "v1beta1/domains")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "gmailpostmastertools.domains.list" call.
// Exactly one of *ListDomainsResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ListDomainsResponse.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 *DomainsListCall) Do(opts ...googleapi.CallOption) (*ListDomainsResponse, 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 := &ListDomainsResponse{
		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": "Lists the domains that have been registered by the client. The order of domains in the response is unspecified and non-deterministic. Newly created domains will not necessarily be added to the end of this list.",
	//   "flatPath": "v1beta1/domains",
	//   "httpMethod": "GET",
	//   "id": "gmailpostmastertools.domains.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Requested page size. Server may return fewer domains than requested. If unspecified, server will pick an appropriate default.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any. This is the value of ListDomainsResponse.next_page_token returned from the previous call to `ListDomains` method.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/domains",
	//   "response": {
	//     "$ref": "ListDomainsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/postmaster.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 *DomainsListCall) Pages(ctx context.Context, f func(*ListDomainsResponse) 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 "gmailpostmastertools.domains.trafficStats.get":

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

// Get: Get traffic statistics for a domain on a specific date. Returns
// PERMISSION_DENIED if user does not have permission to access
// TrafficStats for the domain.
func (r *DomainsTrafficStatsService) Get(name string) *DomainsTrafficStatsGetCall {
	c := &DomainsTrafficStatsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	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 *DomainsTrafficStatsGetCall) Fields(s ...googleapi.Field) *DomainsTrafficStatsGetCall {
	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 *DomainsTrafficStatsGetCall) IfNoneMatch(entityTag string) *DomainsTrafficStatsGetCall {
	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 *DomainsTrafficStatsGetCall) Context(ctx context.Context) *DomainsTrafficStatsGetCall {
	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 *DomainsTrafficStatsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DomainsTrafficStatsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200901")
	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, "v1beta1/{+name}")
	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{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "gmailpostmastertools.domains.trafficStats.get" call.
// Exactly one of *TrafficStats or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *TrafficStats.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 *DomainsTrafficStatsGetCall) Do(opts ...googleapi.CallOption) (*TrafficStats, 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 := &TrafficStats{
		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 traffic statistics for a domain on a specific date. Returns PERMISSION_DENIED if user does not have permission to access TrafficStats for the domain.",
	//   "flatPath": "v1beta1/domains/{domainsId}/trafficStats/{trafficStatsId}",
	//   "httpMethod": "GET",
	//   "id": "gmailpostmastertools.domains.trafficStats.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "The resource name of the traffic statistics to get. E.g., domains/mymail.mydomain.com/trafficStats/20160807.",
	//       "location": "path",
	//       "pattern": "^domains/[^/]+/trafficStats/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "TrafficStats"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/postmaster.readonly"
	//   ]
	// }

}

// method id "gmailpostmastertools.domains.trafficStats.list":

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

// List: List traffic statistics for all available days. Returns
// PERMISSION_DENIED if user does not have permission to access
// TrafficStats for the domain.
func (r *DomainsTrafficStatsService) List(parent string) *DomainsTrafficStatsListCall {
	c := &DomainsTrafficStatsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// EndDateDay sets the optional parameter "endDate.day": Day of month.
// Must be from 1 to 31 and valid for the year and month, or 0 if
// specifying a year by itself or a year and month where the day is not
// significant.
func (c *DomainsTrafficStatsListCall) EndDateDay(endDateDay int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("endDate.day", fmt.Sprint(endDateDay))
	return c
}

// EndDateMonth sets the optional parameter "endDate.month": Month of
// year. Must be from 1 to 12, or 0 if specifying a year without a month
// and day.
func (c *DomainsTrafficStatsListCall) EndDateMonth(endDateMonth int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("endDate.month", fmt.Sprint(endDateMonth))
	return c
}

// EndDateYear sets the optional parameter "endDate.year": Year of date.
// Must be from 1 to 9999, or 0 if specifying a date without a year.
func (c *DomainsTrafficStatsListCall) EndDateYear(endDateYear int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("endDate.year", fmt.Sprint(endDateYear))
	return c
}

// PageSize sets the optional parameter "pageSize": Requested page size.
// Server may return fewer TrafficStats than requested. If unspecified,
// server will pick an appropriate default.
func (c *DomainsTrafficStatsListCall) PageSize(pageSize int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// next_page_token value returned from a previous List request, if any.
// This is the value of ListTrafficStatsResponse.next_page_token
// returned from the previous call to `ListTrafficStats` method.
func (c *DomainsTrafficStatsListCall) PageToken(pageToken string) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// StartDateDay sets the optional parameter "startDate.day": Day of
// month. Must be from 1 to 31 and valid for the year and month, or 0 if
// specifying a year by itself or a year and month where the day is not
// significant.
func (c *DomainsTrafficStatsListCall) StartDateDay(startDateDay int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("startDate.day", fmt.Sprint(startDateDay))
	return c
}

// StartDateMonth sets the optional parameter "startDate.month": Month
// of year. Must be from 1 to 12, or 0 if specifying a year without a
// month and day.
func (c *DomainsTrafficStatsListCall) StartDateMonth(startDateMonth int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("startDate.month", fmt.Sprint(startDateMonth))
	return c
}

// StartDateYear sets the optional parameter "startDate.year": Year of
// date. Must be from 1 to 9999, or 0 if specifying a date without a
// year.
func (c *DomainsTrafficStatsListCall) StartDateYear(startDateYear int64) *DomainsTrafficStatsListCall {
	c.urlParams_.Set("startDate.year", fmt.Sprint(startDateYear))
	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 *DomainsTrafficStatsListCall) Fields(s ...googleapi.Field) *DomainsTrafficStatsListCall {
	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 *DomainsTrafficStatsListCall) IfNoneMatch(entityTag string) *DomainsTrafficStatsListCall {
	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 *DomainsTrafficStatsListCall) Context(ctx context.Context) *DomainsTrafficStatsListCall {
	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 *DomainsTrafficStatsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DomainsTrafficStatsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20200901")
	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, "v1beta1/{+parent}/trafficStats")
	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{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "gmailpostmastertools.domains.trafficStats.list" call.
// Exactly one of *ListTrafficStatsResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ListTrafficStatsResponse.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 *DomainsTrafficStatsListCall) Do(opts ...googleapi.CallOption) (*ListTrafficStatsResponse, 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 := &ListTrafficStatsResponse{
		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 traffic statistics for all available days. Returns PERMISSION_DENIED if user does not have permission to access TrafficStats for the domain.",
	//   "flatPath": "v1beta1/domains/{domainsId}/trafficStats",
	//   "httpMethod": "GET",
	//   "id": "gmailpostmastertools.domains.trafficStats.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "endDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month, or 0 if specifying a year by itself or a year and month where the day is not significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageSize": {
	//       "description": "Requested page size. Server may return fewer TrafficStats than requested. If unspecified, server will pick an appropriate default.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The next_page_token value returned from a previous List request, if any. This is the value of ListTrafficStatsResponse.next_page_token returned from the previous call to `ListTrafficStats` method.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "The resource name of the domain whose traffic statistics we'd like to list. It should have the form `domains/{domain_name}`, where domain_name is the fully qualified domain name.",
	//       "location": "path",
	//       "pattern": "^domains/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "startDate.day": {
	//       "description": "Day of month. Must be from 1 to 31 and valid for the year and month, or 0 if specifying a year by itself or a year and month where the day is not significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/trafficStats",
	//   "response": {
	//     "$ref": "ListTrafficStatsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/postmaster.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 *DomainsTrafficStatsListCall) Pages(ctx context.Context, f func(*ListTrafficStatsResponse) 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)
	}
}
