// 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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) metrics.
	//   "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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) 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 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.
	//
	// **Warning:** The metric is incompatible
	// with
	// [AD_SOURCE_INSTANCE](#Dimension.ENUM_VALUES.AD_SOURCE_INSTANCE)
	// and
	// [MEDIATION_GROUP](#Dimension.ENUM_VALUES.MEDIATION_GROUP) dimensions.
	//   "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.
	//
	// **Warning:** The metric is incompatible
	// with
	// [AD_SOURCE_INSTANCE](#Dimension.ENUM_VALUES.AD_SOURCE_INSTANCE)
	// and
	// [MEDIATION_GROUP](#Dimension.ENUM_VALUES.MEDIATION_GROUP) dimensions.
	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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) metrics.
	//   "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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) 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 *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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) metrics.
	//   "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).
	//
	// **Warning:** The dimension is incompatible
	// with
	// [ESTIMATED_EARNINGS](#Metric.ENUM_VALUES.ESTIMATED_EARNINGS)
	// and
	// [OBSERVED_ECPM](#Metric.ENUM_VALUES.OBSERVED_ECPM) 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 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.
	//
	// **Warning:** The metric is incompatible
	// with
	// [AD_SOURCE_INSTANCE](#Dimension.ENUM_VALUES.AD_SOURCE_INSTANCE)
	// and
	// [MEDIATION_GROUP](#Dimension.ENUM_VALUES.MEDIATION_GROUP) dimensions.
	//   "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.
	//
	// **Warning:** The metric is incompatible
	// with
	// [AD_SOURCE_INSTANCE](#Dimension.ENUM_VALUES.AD_SOURCE_INSTANCE)
	// and
	// [MEDIATION_GROUP](#Dimension.ENUM_VALUES.MEDIATION_GROUP) dimensions.
	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](#Met
	// ric.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](#Met
	// ric.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](#Met
	// ric.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 did match the request.
	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/20200714")
	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": "Required. Resource name of the publisher account to retrieve.\nExample: 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/20200714")
	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.\nCurrently, 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\nthat this is a continuation of a prior `ListPublisherAccounts` call, and\nthat 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/20200714")
	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\nspecification.",
	//   "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.\nExample: 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/20200714")
	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\nspecification.",
	//   "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.\nExample: accounts/pub-9876543210987654",
	//       "location": "path",
	//       "pattern": "^accounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1/{+parent}/networkReport:generate",
	//   "request": {
	//     "$ref": "GenerateNetworkReportRequest"
	//   },
	//   "response": {
	//     "$ref": "GenerateNetworkReportResponse"
	//   }
	// }

}
