// 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/"

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	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, e.g. a birthday.
// The time of day and time zone are either specified elsewhere or are
// not significant. The date is relative to the Proleptic Gregorian
// Calendar. This can represent: * A full date, with non-zero year,
// month and day values * A month and day value, with a zero year, e.g.
// an anniversary * A year on its own, with zero month and day values *
// A year and month value, with a zero day, e.g. a credit card
// expiration date Related types are google.type.TimeOfDay and
// `google.protobuf.Timestamp`.
type Date struct {
	// 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.
	Day int64 `json:"day,omitempty"`

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

	// Year: Year of date. Must be from 1 to 9999, or 0 if specifying 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 (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. Any other values
	// are treated as 100000.
	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 (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 (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. Any other values
	// are treated as 100000.
	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. **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. **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/20200820")
	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"
	//   }
	// }

}

// 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/20200820")
	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"
	//   }
	// }

}

// 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/20200820")
	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"
	//   }
	// }

}

// 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/20200820")
	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"
	//   }
	// }

}
