// 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 admob provides access to the AdMob API.
//
// For product documentation, see: https://developers.google.com/admob/api/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/admob/v1"
//   ...
//   ctx := context.Background()
//   admobService, err := admob.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:
//
//   admobService, err := admob.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, ...)
//   admobService, err := admob.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package admob // import "google.golang.org/api/admob/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"
	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 = "admob:v1"
const apiName = "admob"
const apiVersion = "v1"
const basePath = "https://admob.googleapis.com/"
const mtlsBasePath = "https://admob.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// See your AdMob data
	AdmobReportScope = "https://www.googleapis.com/auth/admob.report"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/admob.report",
	)
	// 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.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.MediationReport = NewAccountsMediationReportService(s)
	rs.NetworkReport = NewAccountsNetworkReportService(s)
	return rs
}

type AccountsService struct {
	s *Service

	MediationReport *AccountsMediationReportService

	NetworkReport *AccountsNetworkReportService
}

func NewAccountsMediationReportService(s *Service) *AccountsMediationReportService {
	rs := &AccountsMediationReportService{s: s}
	return rs
}

type AccountsMediationReportService struct {
	s *Service
}

func NewAccountsNetworkReportService(s *Service) *AccountsNetworkReportService {
	rs := &AccountsNetworkReportService{s: s}
	return rs
}

type AccountsNetworkReportService struct {
	s *Service
}

// Date: Represents a whole or partial calendar date, such as a
// birthday. The time of day and time zone are either specified
// elsewhere or are insignificant. The date is relative to the Gregorian
// Calendar. This can represent one of the following: * A full date,
// with non-zero year, month, and day values * A month and day value,
// with a zero year, such as an anniversary * A year on its own, with
// zero month and day values * A year and month value, with a zero day,
// such as a credit card expiration date Related types are
// google.type.TimeOfDay and `google.protobuf.Timestamp`.
type Date struct {
	// Day: Day of a month. Must be from 1 to 31 and valid for the year and
	// month, or 0 to specify a year by itself or a year and month where the
	// day isn't significant.
	Day int64 `json:"day,omitempty"`

	// Month: Month of a year. Must be from 1 to 12, or 0 to specify a year
	// without a month and day.
	Month int64 `json:"month,omitempty"`

	// Year: Year of the date. Must be from 1 to 9999, or 0 to specify a
	// date without a year.
	Year int64 `json:"year,omitempty"`

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

// DateRange: Specification of a single date range. Both dates are
// inclusive.
type DateRange struct {
	// EndDate: End date of the date range, inclusive. Must be greater than
	// or equal to the start date.
	EndDate *Date `json:"endDate,omitempty"`

	// StartDate: Start date of the date range, inclusive. Must be less than
	// or equal to the end date.
	StartDate *Date `json:"startDate,omitempty"`

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

// GenerateMediationReportRequest: Request to generate an AdMob
// Mediation report.
type GenerateMediationReportRequest struct {
	// ReportSpec: Network report specification.
	ReportSpec *MediationReportSpec `json:"reportSpec,omitempty"`

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

// GenerateMediationReportResponse: The streaming response for the AdMob
// Mediation report where the first response contains the report header,
// then a stream of row responses, and finally a footer as the last
// response message. For example: [{ "header": { "date_range": {
// "start_date": {"year": 2018, "month": 9, "day": 1}, "end_date":
// {"year": 2018, "month": 9, "day": 1} }, "localization_settings": {
// "currency_code": "USD", "language_code": "en-US" } } }, { "row": {
// "dimension_values": { "DATE": {"value": "20180918"}, "APP": {
// "value": "ca-app-pub-8123415297019784~1001342552", "display_label":
// "My app name!" } }, "metric_values": { "ESTIMATED_EARNINGS":
// {"decimal_value": "1324746"} } } }, { "footer":
// {"matching_row_count": 1} }]
type GenerateMediationReportResponse struct {
	// Footer: Additional information about the generated report, such as
	// warnings about the data.
	Footer *ReportFooter `json:"footer,omitempty"`

	// Header: Report generation settings that describes the report
	// contents, such as the report date range and localization settings.
	Header *ReportHeader `json:"header,omitempty"`

	// Row: Actual report data.
	Row *ReportRow `json:"row,omitempty"`

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

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

// GenerateNetworkReportRequest: Request to generate an AdMob Network
// report.
type GenerateNetworkReportRequest struct {
	// ReportSpec: Network report specification.
	ReportSpec *NetworkReportSpec `json:"reportSpec,omitempty"`

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

// GenerateNetworkReportResponse: The streaming response for the AdMob
// Network report where the first response contains the report header,
// then a stream of row responses, and finally a footer as the last
// response message. For example: [{ "header": { "dateRange": {
// "startDate": {"year": 2018, "month": 9, "day": 1}, "endDate":
// {"year": 2018, "month": 9, "day": 1} }, "localizationSettings": {
// "currencyCode": "USD", "languageCode": "en-US" } } }, { "row": {
// "dimensionValues": { "DATE": {"value": "20180918"}, "APP": { "value":
// "ca-app-pub-8123415297019784~1001342552", displayLabel: "My app
// name!" } }, "metricValues": { "ESTIMATED_EARNINGS": {"microsValue":
// 6500000} } } }, { "footer": {"matchingRowCount": 1} }]
type GenerateNetworkReportResponse struct {
	// Footer: Additional information about the generated report, such as
	// warnings about the data.
	Footer *ReportFooter `json:"footer,omitempty"`

	// Header: Report generation settings that describes the report
	// contents, such as the report date range and localization settings.
	Header *ReportHeader `json:"header,omitempty"`

	// Row: Actual report data.
	Row *ReportRow `json:"row,omitempty"`

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

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

// ListPublisherAccountsResponse: Response for the publisher account
// list request.
type ListPublisherAccountsResponse struct {
	// Account: Publisher that the client credentials can access.
	Account []*PublisherAccount `json:"account,omitempty"`

	// NextPageToken: If not empty, indicates that there might be more
	// accounts for the request; you must pass this value in a new
	// `ListPublisherAccountsRequest`.
	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. "Account") 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. "Account") 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 *ListPublisherAccountsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod ListPublisherAccountsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LocalizationSettings: Localization settings for reports, such as
// currency and language. It affects how metrics are calculated.
type LocalizationSettings struct {
	// CurrencyCode: Currency code of the earning related metrics, which is
	// the 3-letter code defined in ISO 4217. The daily average rate is used
	// for the currency conversion. Defaults to the account currency code if
	// unspecified.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// LanguageCode: Language used for any localized text, such as some
	// dimension value display labels. The language tag defined in the IETF
	// BCP47. Defaults to 'en-US' if unspecified.
	LanguageCode string `json:"languageCode,omitempty"`

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

// MediationReportSpec: The specification for generating an AdMob
// Mediation report. For example, the specification to get observed ECPM
// sliced by ad source and app for the 'US' and 'CN' countries can look
// like the following example: { "date_range": { "start_date": {"year":
// 2018, "month": 9, "day": 1}, "end_date": {"year": 2018, "month": 9,
// "day": 30} }, "dimensions": ["AD_SOURCE", "APP", "COUNTRY"],
// "metrics": ["OBSERVED_ECPM"], "dimension_filters": [ { "dimension":
// "COUNTRY", "matches_any": {"values": [{"value": "US", "value":
// "CN"}]} } ], "sort_conditions": [ {"dimension":"APP", order:
// "ASCENDING"} ], "localization_settings": { "currency_code": "USD",
// "language_code": "en-US" } } For a better understanding, you can
// treat the preceding specification like the following pseudo SQL:
// SELECT AD_SOURCE, APP, COUNTRY, OBSERVED_ECPM FROM MEDIATION_REPORT
// WHERE DATE >= '2018-09-01' AND DATE <= '2018-09-30' AND COUNTRY IN
// ('US', 'CN') GROUP BY AD_SOURCE, APP, COUNTRY ORDER BY APP ASC;
type MediationReportSpec struct {
	// DateRange: The date range for which the report is generated.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: Describes which report rows to match based on their
	// dimension values.
	DimensionFilters []*MediationReportSpecDimensionFilter `json:"dimensionFilters,omitempty"`

	// Dimensions: List of dimensions of the report. The value combination
	// of these dimensions determines the row of the report. If no
	// dimensions are specified, the report returns a single row of
	// requested metrics for the entire account.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_SOURCE" - The [unique ID of the ad
	// source](/admob/api/v1/ad_sources) (for example, "5450213213286189855"
	// and "AdMob Network" as label value).
	//   "AD_SOURCE_INSTANCE" - The unique ID of the ad source instance (for
	// example, "ca-app-pub-1234#5678" and "AdMob (default)" as label
	// value).
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/8790"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "MEDIATION_GROUP" - The unique ID of the mediation group (for
	// example, "ca-app-pub-1234:mg:1234" and "AdMob (default)" as label
	// value).
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimensions []string `json:"dimensions,omitempty"`

	// LocalizationSettings: Localization settings of the report.
	LocalizationSettings *LocalizationSettings `json:"localizationSettings,omitempty"`

	// MaxReportRows: Maximum number of report data rows to return. If the
	// value is not set, the API returns as many rows as possible, up to
	// 100000. Acceptable values are 1-100000, inclusive. Values larger than
	// 100000 return an error.
	MaxReportRows int64 `json:"maxReportRows,omitempty"`

	// Metrics: List of metrics of the report. A report must specify at
	// least one metric.
	//
	// Possible values:
	//   "METRIC_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "AD_REQUESTS" - The number of requests. The value is an integer.
	//   "CLICKS" - The number of times a user clicks an ad. The value is an
	// integer.
	//   "ESTIMATED_EARNINGS" - The estimated earnings of the AdMob
	// publisher. The currency unit (USD, EUR, or other) of the earning
	// metrics are determined by the localization setting for currency. The
	// amount is in micros. For example, $6.50 would be represented as
	// 6500000. Estimated earnings per mediation group and per ad source
	// instance level is supported dating back to October 20, 2019.
	// Third-party estimated earnings will show 0 for dates prior to October
	// 20, 2019.
	//   "IMPRESSIONS" - The total number of ads shown to users. The value
	// is an integer.
	//   "IMPRESSION_CTR" - The ratio of clicks over impressions. The value
	// is a double precision (approximate) decimal value.
	//   "MATCHED_REQUESTS" - The number of times ads are returned in
	// response to a request. The value is an integer.
	//   "MATCH_RATE" - The ratio of matched ad requests over the total ad
	// requests. The value is a double precision (approximate) decimal
	// value.
	//   "OBSERVED_ECPM" - The third-party ad network's estimated average
	// eCPM. The currency unit (USD, EUR, or other) of the earning metrics
	// are determined by the localization setting for currency. The amount
	// is in micros. For example, $2.30 would be represented as 2300000. The
	// estimated average eCPM per mediation group and per ad source instance
	// level is supported dating back to October 20, 2019. Third-party
	// estimated average eCPM will show 0 for dates prior to October 20,
	// 2019.
	Metrics []string `json:"metrics,omitempty"`

	// SortConditions: Describes the sorting of report rows. The order of
	// the condition in the list defines its precedence; the earlier the
	// condition, the higher its precedence. If no sort conditions are
	// specified, the row ordering is undefined.
	SortConditions []*MediationReportSpecSortCondition `json:"sortConditions,omitempty"`

	// TimeZone: A report time zone. Accepts an IANA TZ name values, such as
	// "America/Los_Angeles." If no time zone is defined, the account
	// default takes effect. Check default value by the get account action.
	// **Warning:** The "America/Los_Angeles" is the only supported value at
	// the moment.
	TimeZone string `json:"timeZone,omitempty"`

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

// MediationReportSpecDimensionFilter: Describes which report rows to
// match based on their dimension values.
type MediationReportSpecDimensionFilter struct {
	// Dimension: Applies the filter criterion to the specified dimension.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_SOURCE" - The [unique ID of the ad
	// source](/admob/api/v1/ad_sources) (for example, "5450213213286189855"
	// and "AdMob Network" as label value).
	//   "AD_SOURCE_INSTANCE" - The unique ID of the ad source instance (for
	// example, "ca-app-pub-1234#5678" and "AdMob (default)" as label
	// value).
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/8790"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "MEDIATION_GROUP" - The unique ID of the mediation group (for
	// example, "ca-app-pub-1234:mg:1234" and "AdMob (default)" as label
	// value).
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimension string `json:"dimension,omitempty"`

	// MatchesAny: Matches a row if its value for the specified dimension is
	// in one of the values specified in this condition.
	MatchesAny *StringList `json:"matchesAny,omitempty"`

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

// MediationReportSpecSortCondition: Sorting direction to be applied on
// a dimension or a metric.
type MediationReportSpecSortCondition struct {
	// Dimension: Sort by the specified dimension.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_SOURCE" - The [unique ID of the ad
	// source](/admob/api/v1/ad_sources) (for example, "5450213213286189855"
	// and "AdMob Network" as label value).
	//   "AD_SOURCE_INSTANCE" - The unique ID of the ad source instance (for
	// example, "ca-app-pub-1234#5678" and "AdMob (default)" as label
	// value).
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/8790"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "MEDIATION_GROUP" - The unique ID of the mediation group (for
	// example, "ca-app-pub-1234:mg:1234" and "AdMob (default)" as label
	// value).
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimension string `json:"dimension,omitempty"`

	// Metric: Sort by the specified metric.
	//
	// Possible values:
	//   "METRIC_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "AD_REQUESTS" - The number of requests. The value is an integer.
	//   "CLICKS" - The number of times a user clicks an ad. The value is an
	// integer.
	//   "ESTIMATED_EARNINGS" - The estimated earnings of the AdMob
	// publisher. The currency unit (USD, EUR, or other) of the earning
	// metrics are determined by the localization setting for currency. The
	// amount is in micros. For example, $6.50 would be represented as
	// 6500000. Estimated earnings per mediation group and per ad source
	// instance level is supported dating back to October 20, 2019.
	// Third-party estimated earnings will show 0 for dates prior to October
	// 20, 2019.
	//   "IMPRESSIONS" - The total number of ads shown to users. The value
	// is an integer.
	//   "IMPRESSION_CTR" - The ratio of clicks over impressions. The value
	// is a double precision (approximate) decimal value.
	//   "MATCHED_REQUESTS" - The number of times ads are returned in
	// response to a request. The value is an integer.
	//   "MATCH_RATE" - The ratio of matched ad requests over the total ad
	// requests. The value is a double precision (approximate) decimal
	// value.
	//   "OBSERVED_ECPM" - The third-party ad network's estimated average
	// eCPM. The currency unit (USD, EUR, or other) of the earning metrics
	// are determined by the localization setting for currency. The amount
	// is in micros. For example, $2.30 would be represented as 2300000. The
	// estimated average eCPM per mediation group and per ad source instance
	// level is supported dating back to October 20, 2019. Third-party
	// estimated average eCPM will show 0 for dates prior to October 20,
	// 2019.
	Metric string `json:"metric,omitempty"`

	// Order: Sorting order of the dimension or metric.
	//
	// Possible values:
	//   "SORT_ORDER_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "ASCENDING" - Sort dimension value or metric value in ascending
	// order.
	//   "DESCENDING" - Sort dimension value or metric value in descending
	// order.
	Order string `json:"order,omitempty"`

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

// NetworkReportSpec: The specification for generating an AdMob Network
// report. For example, the specification to get clicks and estimated
// earnings for only the 'US' and 'CN' countries can look like the
// following example: { 'date_range': { 'start_date': {'year': 2018,
// 'month': 9, 'day': 1}, 'end_date': {'year': 2018, 'month': 9, 'day':
// 30} }, 'dimensions': ['DATE', 'APP', 'COUNTRY'], 'metrics':
// ['CLICKS', 'ESTIMATED_EARNINGS'], 'dimension_filters': [ {
// 'dimension': 'COUNTRY', 'matches_any': {'values': [{'value': 'US',
// 'value': 'CN'}]} } ], 'sort_conditions': [ {'dimension':'APP', order:
// 'ASCENDING'}, {'metric':'CLICKS', order: 'DESCENDING'} ],
// 'localization_settings': { 'currency_code': 'USD', 'language_code':
// 'en-US' } } For a better understanding, you can treat the preceding
// specification like the following pseudo SQL: SELECT DATE, APP,
// COUNTRY, CLICKS, ESTIMATED_EARNINGS FROM NETWORK_REPORT WHERE DATE >=
// '2018-09-01' AND DATE <= '2018-09-30' AND COUNTRY IN ('US', 'CN')
// GROUP BY DATE, APP, COUNTRY ORDER BY APP ASC, CLICKS DESC;
type NetworkReportSpec struct {
	// DateRange: The date range for which the report is generated.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: Describes which report rows to match based on their
	// dimension values.
	DimensionFilters []*NetworkReportSpecDimensionFilter `json:"dimensionFilters,omitempty"`

	// Dimensions: List of dimensions of the report. The value combination
	// of these dimensions determines the row of the report. If no
	// dimensions are specified, the report returns a single row of
	// requested metrics for the entire account.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/1234"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "AD_TYPE" - Type of the ad (for example, "text" or "image"), an ad
	// delivery dimension. **Warning:** The dimension is incompatible with
	// [AD_REQUESTS](#Metric.ENUM_VALUES.AD_REQUESTS),
	// [MATCH_RATE](#Metric.ENUM_VALUES.MATCH_RATE) and
	// [IMPRESSION_RPM](#Metric.ENUM_VALUES.IMPRESSION_RPM) metrics.
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimensions []string `json:"dimensions,omitempty"`

	// LocalizationSettings: Localization settings of the report.
	LocalizationSettings *LocalizationSettings `json:"localizationSettings,omitempty"`

	// MaxReportRows: Maximum number of report data rows to return. If the
	// value is not set, the API returns as many rows as possible, up to
	// 100000. Acceptable values are 1-100000, inclusive. Values larger than
	// 100000 return an error.
	MaxReportRows int64 `json:"maxReportRows,omitempty"`

	// Metrics: List of metrics of the report. A report must specify at
	// least one metric.
	//
	// Possible values:
	//   "METRIC_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "AD_REQUESTS" - The number of ad requests. The value is an integer.
	// **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "CLICKS" - The number of times a user clicks an ad. The value is an
	// integer.
	//   "ESTIMATED_EARNINGS" - The estimated earnings of the AdMob
	// publisher. The currency unit (USD, EUR, or other) of the earning
	// metrics are determined by the localization setting for currency. The
	// amount is in micros. For example, $6.50 would be represented as
	// 6500000.
	//   "IMPRESSIONS" - The total number of ads shown to users. The value
	// is an integer.
	//   "IMPRESSION_CTR" - The ratio of clicks over impressions. The value
	// is a double precision (approximate) decimal value.
	//   "IMPRESSION_RPM" - The estimated earnings per thousand ad
	// impressions. The value is in micros. For example, $1.03 would be
	// represented as 1030000. Equivalent to eCPM in the AdMob UI.
	// **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "MATCHED_REQUESTS" - The number of times ads are returned in
	// response to a request. The value is an integer.
	//   "MATCH_RATE" - The ratio of matched ad requests over the total ad
	// requests. The value is a double precision (approximate) decimal
	// value. **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "SHOW_RATE" - The ratio of ads that are displayed over ads that are
	// returned, defined as impressions / matched requests. The value is a
	// double precision (approximate) decimal value.
	Metrics []string `json:"metrics,omitempty"`

	// SortConditions: Describes the sorting of report rows. The order of
	// the condition in the list defines its precedence; the earlier the
	// condition, the higher its precedence. If no sort conditions are
	// specified, the row ordering is undefined.
	SortConditions []*NetworkReportSpecSortCondition `json:"sortConditions,omitempty"`

	// TimeZone: A report time zone. Accepts an IANA TZ name values, such as
	// "America/Los_Angeles." If no time zone is defined, the account
	// default takes effect. Check default value by the get account action.
	// **Warning:** The "America/Los_Angeles" is the only supported value at
	// the moment.
	TimeZone string `json:"timeZone,omitempty"`

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

// NetworkReportSpecDimensionFilter: Describes which report rows to
// match based on their dimension values.
type NetworkReportSpecDimensionFilter struct {
	// Dimension: Applies the filter criterion to the specified dimension.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/1234"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "AD_TYPE" - Type of the ad (for example, "text" or "image"), an ad
	// delivery dimension. **Warning:** The dimension is incompatible with
	// [AD_REQUESTS](#Metric.ENUM_VALUES.AD_REQUESTS),
	// [MATCH_RATE](#Metric.ENUM_VALUES.MATCH_RATE) and
	// [IMPRESSION_RPM](#Metric.ENUM_VALUES.IMPRESSION_RPM) metrics.
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimension string `json:"dimension,omitempty"`

	// MatchesAny: Matches a row if its value for the specified dimension is
	// in one of the values specified in this condition.
	MatchesAny *StringList `json:"matchesAny,omitempty"`

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

// NetworkReportSpecSortCondition: Sorting direction to be applied on a
// dimension or a metric.
type NetworkReportSpecSortCondition struct {
	// Dimension: Sort by the specified dimension.
	//
	// Possible values:
	//   "DIMENSION_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "DATE" - A date in the YYYY-MM-DD format (for example,
	// "2018-12-21"). Requests can specify at most one time dimension.
	//   "MONTH" - A month in the YYYY-MM format (for example, "2018-12").
	// Requests can specify at most one time dimension.
	//   "WEEK" - The date of the first day of a week in the YYYY-MM-DD
	// format (for example, "2018-12-21"). Requests can specify at most one
	// time dimension.
	//   "AD_UNIT" - The unique ID of the ad unit (for example,
	// "ca-app-pub-1234/1234"). If AD_UNIT dimension is specified, then APP
	// is included automatically.
	//   "APP" - The unique ID of the mobile application (for example,
	// "ca-app-pub-1234~1234").
	//   "AD_TYPE" - Type of the ad (for example, "text" or "image"), an ad
	// delivery dimension. **Warning:** The dimension is incompatible with
	// [AD_REQUESTS](#Metric.ENUM_VALUES.AD_REQUESTS),
	// [MATCH_RATE](#Metric.ENUM_VALUES.MATCH_RATE) and
	// [IMPRESSION_RPM](#Metric.ENUM_VALUES.IMPRESSION_RPM) metrics.
	//   "COUNTRY" - CLDR country code of the place where the ad
	// views/clicks occur (for example, "US" or "FR"). This is a geography
	// dimension.
	//   "FORMAT" - Format of the ad unit (for example, "banner", "native"),
	// an ad delivery dimension.
	//   "PLATFORM" - Mobile OS platform of the app (for example, "Android"
	// or "iOS").
	Dimension string `json:"dimension,omitempty"`

	// Metric: Sort by the specified metric.
	//
	// Possible values:
	//   "METRIC_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "AD_REQUESTS" - The number of ad requests. The value is an integer.
	// **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "CLICKS" - The number of times a user clicks an ad. The value is an
	// integer.
	//   "ESTIMATED_EARNINGS" - The estimated earnings of the AdMob
	// publisher. The currency unit (USD, EUR, or other) of the earning
	// metrics are determined by the localization setting for currency. The
	// amount is in micros. For example, $6.50 would be represented as
	// 6500000.
	//   "IMPRESSIONS" - The total number of ads shown to users. The value
	// is an integer.
	//   "IMPRESSION_CTR" - The ratio of clicks over impressions. The value
	// is a double precision (approximate) decimal value.
	//   "IMPRESSION_RPM" - The estimated earnings per thousand ad
	// impressions. The value is in micros. For example, $1.03 would be
	// represented as 1030000. Equivalent to eCPM in the AdMob UI.
	// **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "MATCHED_REQUESTS" - The number of times ads are returned in
	// response to a request. The value is an integer.
	//   "MATCH_RATE" - The ratio of matched ad requests over the total ad
	// requests. The value is a double precision (approximate) decimal
	// value. **Warning:** The metric is incompatible with
	// [AD_TYPE](#Dimension.ENUM_VALUES.AD_TYPE) dimension.
	//   "SHOW_RATE" - The ratio of ads that are displayed over ads that are
	// returned, defined as impressions / matched requests. The value is a
	// double precision (approximate) decimal value.
	Metric string `json:"metric,omitempty"`

	// Order: Sorting order of the dimension or metric.
	//
	// Possible values:
	//   "SORT_ORDER_UNSPECIFIED" - Default value for an unset field. Do not
	// use.
	//   "ASCENDING" - Sort dimension value or metric value in ascending
	// order.
	//   "DESCENDING" - Sort dimension value or metric value in descending
	// order.
	Order string `json:"order,omitempty"`

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

// PublisherAccount: A publisher account contains information relevant
// to the use of this API, such as the time zone used for the reports.
type PublisherAccount struct {
	// CurrencyCode: Currency code of the earning-related metrics, which is
	// the 3-letter code defined in ISO 4217. The daily average rate is used
	// for the currency conversion.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// Name: Resource name of this account. Format is
	// accounts/{publisher_id}.
	Name string `json:"name,omitempty"`

	// PublisherId: The unique ID by which this publisher account can be
	// identified in the API requests (for example, pub-1234567890).
	PublisherId string `json:"publisherId,omitempty"`

	// ReportingTimeZone: The time zone that is used in reports that are
	// generated for this account. The value is a time-zone ID as specified
	// by the CLDR project, for example, "America/Los_Angeles".
	ReportingTimeZone string `json:"reportingTimeZone,omitempty"`

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

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

// ReportFooter: Groups data available after report generation, for
// example, warnings and row counts. Always sent as the last message in
// the stream response.
type ReportFooter struct {
	// MatchingRowCount: Total number of rows that matched the request.
	// Warning: This count does NOT always match the number of rows in the
	// response. Do not make that assumption when processing the response.
	MatchingRowCount int64 `json:"matchingRowCount,omitempty,string"`

	// Warnings: Warnings associated with generation of the report.
	Warnings []*ReportWarning `json:"warnings,omitempty"`

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

// ReportHeader: Groups data helps to treat the generated report. Always
// sent as a first message in the stream response.
type ReportHeader struct {
	// DateRange: The date range for which the report is generated. This is
	// identical to the range specified in the report request.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// LocalizationSettings: Localization settings of the report. This is
	// identical to the settings in the report request.
	LocalizationSettings *LocalizationSettings `json:"localizationSettings,omitempty"`

	// ReportingTimeZone: The report time zone. The value is a time-zone ID
	// as specified by the CLDR project, for example, "America/Los_Angeles".
	ReportingTimeZone string `json:"reportingTimeZone,omitempty"`

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

// ReportRow: A row of the returning report.
type ReportRow struct {
	// DimensionValues: Map of dimension values in a row, with keys as enum
	// name of the dimensions.
	DimensionValues map[string]ReportRowDimensionValue `json:"dimensionValues,omitempty"`

	// MetricValues: Map of metric values in a row, with keys as enum name
	// of the metrics. If a metric being requested has no value returned,
	// the map will not include it.
	MetricValues map[string]ReportRowMetricValue `json:"metricValues,omitempty"`

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

// ReportRowDimensionValue: Representation of a dimension value.
type ReportRowDimensionValue struct {
	// DisplayLabel: The localized string representation of the value. If
	// unspecified, the display label should be derived from the value.
	DisplayLabel string `json:"displayLabel,omitempty"`

	// Value: Dimension value in the format specified in the report's spec
	// Dimension enum.
	Value string `json:"value,omitempty"`

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

// ReportRowMetricValue: Representation of a metric value.
type ReportRowMetricValue struct {
	// DoubleValue: Double precision (approximate) decimal values. Rates are
	// from 0 to 1.
	DoubleValue float64 `json:"doubleValue,omitempty"`

	// IntegerValue: Metric integer value.
	IntegerValue int64 `json:"integerValue,omitempty,string"`

	// MicrosValue: Amount in micros. One million is equivalent to one unit.
	// Currency value is in the unit (USD, EUR or other) specified by the
	// request. For example, $6.50 whould be represented as 6500000 micros.
	MicrosValue int64 `json:"microsValue,omitempty,string"`

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

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

// ReportWarning: Warnings associated with generation of the report.
type ReportWarning struct {
	// Description: Describes the details of the warning message, in
	// English.
	Description string `json:"description,omitempty"`

	// Type: Type of the warning.
	//
	// Possible values:
	//   "TYPE_UNSPECIFIED" - Default value for an unset field. Do not use.
	//   "DATA_BEFORE_ACCOUNT_TIMEZONE_CHANGE" - Some data in this report is
	// aggregated based on a time zone different from the requested time
	// zone. This could happen if a local time-zone report has the start
	// time before the last time this time zone changed. The description
	// field will contain the date of the last time zone change.
	//   "DATA_DELAYED" - There is an unusual delay in processing the source
	// data for the requested date range. The report results might be less
	// up to date than usual. AdMob is aware of the issue and is actively
	// working to resolve it.
	//   "OTHER" - Warnings that are exposed without a specific type. Useful
	// when new warning types are added but the API is not changed yet.
	//   "REPORT_CURRENCY_NOT_ACCOUNT_CURRENCY" - The currency being
	// requested is not the account currency. The earning metrics will be
	// based on the requested currency, and thus not a good estimation of
	// the final payment anymore, due to the currency rate fluctuation.
	Type string `json:"type,omitempty"`

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

// StringList: List of string values.
type StringList struct {
	// Values: The string values.
	Values []string `json:"values,omitempty"`

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

// method id "admob.accounts.get":

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

// Get: Gets information about the specified AdMob publisher account.
func (r *AccountsService) Get(name string) *AccountsGetCall {
	c := &AccountsGetCall{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 *AccountsGetCall) Fields(s ...googleapi.Field) *AccountsGetCall {
	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 *AccountsGetCall) IfNoneMatch(entityTag string) *AccountsGetCall {
	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 *AccountsGetCall) Context(ctx context.Context) *AccountsGetCall {
	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 *AccountsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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/{+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 "admob.accounts.get" call.
// Exactly one of *PublisherAccount or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PublisherAccount.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 *AccountsGetCall) Do(opts ...googleapi.CallOption) (*PublisherAccount, 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 := &PublisherAccount{
		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 information about the specified AdMob publisher account.",
	//   "flatPath": "v1/accounts/{accountsId}",
	//   "httpMethod": "GET",
	//   "id": "admob.accounts.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Resource name of the publisher account to retrieve. Example: accounts/pub-9876543210987654",
	//       "location": "path",
	//       "pattern": "^accounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+name}",
	//   "response": {
	//     "$ref": "PublisherAccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/admob.report"
	//   ]
	// }

}

// method id "admob.accounts.list":

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

// List: Lists the AdMob publisher account accessible with the client
// credential. Currently, all credentials have access to at most one
// AdMob account.
func (r *AccountsService) List() *AccountsListCall {
	c := &AccountsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// PageSize sets the optional parameter "pageSize": Maximum number of
// accounts to return.
func (c *AccountsListCall) PageSize(pageSize int64) *AccountsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListPublisherAccountsResponse`; indicates that this is a
// continuation of a prior `ListPublisherAccounts` call, and that the
// system should return the next page of data.
func (c *AccountsListCall) PageToken(pageToken string) *AccountsListCall {
	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 *AccountsListCall) Fields(s ...googleapi.Field) *AccountsListCall {
	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 *AccountsListCall) IfNoneMatch(entityTag string) *AccountsListCall {
	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 *AccountsListCall) Context(ctx context.Context) *AccountsListCall {
	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 *AccountsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	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")
	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 "admob.accounts.list" call.
// Exactly one of *ListPublisherAccountsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ListPublisherAccountsResponse.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 *AccountsListCall) Do(opts ...googleapi.CallOption) (*ListPublisherAccountsResponse, 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 := &ListPublisherAccountsResponse{
		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 AdMob publisher account accessible with the client credential. Currently, all credentials have access to at most one AdMob account.",
	//   "flatPath": "v1/accounts",
	//   "httpMethod": "GET",
	//   "id": "admob.accounts.list",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Maximum number of accounts to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value returned by the last `ListPublisherAccountsResponse`; indicates that this is a continuation of a prior `ListPublisherAccounts` call, and that the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/accounts",
	//   "response": {
	//     "$ref": "ListPublisherAccountsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/admob.report"
	//   ]
	// }

}

// 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 *AccountsListCall) Pages(ctx context.Context, f func(*ListPublisherAccountsResponse) 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 "admob.accounts.mediationReport.generate":

type AccountsMediationReportGenerateCall struct {
	s                              *Service
	parent                         string
	generatemediationreportrequest *GenerateMediationReportRequest
	urlParams_                     gensupport.URLParams
	ctx_                           context.Context
	header_                        http.Header
}

// Generate: Generates an AdMob Mediation report based on the provided
// report specification.
func (r *AccountsMediationReportService) Generate(parent string, generatemediationreportrequest *GenerateMediationReportRequest) *AccountsMediationReportGenerateCall {
	c := &AccountsMediationReportGenerateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.generatemediationreportrequest = generatemediationreportrequest
	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 *AccountsMediationReportGenerateCall) Fields(s ...googleapi.Field) *AccountsMediationReportGenerateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *AccountsMediationReportGenerateCall) Context(ctx context.Context) *AccountsMediationReportGenerateCall {
	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 *AccountsMediationReportGenerateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsMediationReportGenerateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.generatemediationreportrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/mediationReport:generate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "admob.accounts.mediationReport.generate" call.
// Exactly one of *GenerateMediationReportResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GenerateMediationReportResponse.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 *AccountsMediationReportGenerateCall) Do(opts ...googleapi.CallOption) (*GenerateMediationReportResponse, 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 := &GenerateMediationReportResponse{
		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": "Generates an AdMob Mediation report based on the provided report specification.",
	//   "flatPath": "v1/accounts/{accountsId}/mediationReport:generate",
	//   "httpMethod": "POST",
	//   "id": "admob.accounts.mediationReport.generate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Resource name of the account to generate the report for. Example: accounts/pub-9876543210987654",
	//       "location": "path",
	//       "pattern": "^accounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/mediationReport:generate",
	//   "request": {
	//     "$ref": "GenerateMediationReportRequest"
	//   },
	//   "response": {
	//     "$ref": "GenerateMediationReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/admob.report"
	//   ]
	// }

}

// method id "admob.accounts.networkReport.generate":

type AccountsNetworkReportGenerateCall struct {
	s                            *Service
	parent                       string
	generatenetworkreportrequest *GenerateNetworkReportRequest
	urlParams_                   gensupport.URLParams
	ctx_                         context.Context
	header_                      http.Header
}

// Generate: Generates an AdMob Network report based on the provided
// report specification.
func (r *AccountsNetworkReportService) Generate(parent string, generatenetworkreportrequest *GenerateNetworkReportRequest) *AccountsNetworkReportGenerateCall {
	c := &AccountsNetworkReportGenerateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.generatenetworkreportrequest = generatenetworkreportrequest
	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 *AccountsNetworkReportGenerateCall) Fields(s ...googleapi.Field) *AccountsNetworkReportGenerateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	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 *AccountsNetworkReportGenerateCall) Context(ctx context.Context) *AccountsNetworkReportGenerateCall {
	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 *AccountsNetworkReportGenerateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsNetworkReportGenerateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/20201002")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.generatenetworkreportrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+parent}/networkReport:generate")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", 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 "admob.accounts.networkReport.generate" call.
// Exactly one of *GenerateNetworkReportResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *GenerateNetworkReportResponse.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 *AccountsNetworkReportGenerateCall) Do(opts ...googleapi.CallOption) (*GenerateNetworkReportResponse, 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 := &GenerateNetworkReportResponse{
		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": "Generates an AdMob Network report based on the provided report specification.",
	//   "flatPath": "v1/accounts/{accountsId}/networkReport:generate",
	//   "httpMethod": "POST",
	//   "id": "admob.accounts.networkReport.generate",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Resource name of the account to generate the report for. Example: accounts/pub-9876543210987654",
	//       "location": "path",
	//       "pattern": "^accounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/networkReport:generate",
	//   "request": {
	//     "$ref": "GenerateNetworkReportRequest"
	//   },
	//   "response": {
	//     "$ref": "GenerateNetworkReportResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/admob.report"
	//   ]
	// }

}
