// 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"
	htransport "google.golang.org/api/transport/http"
)

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

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

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	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": 30}
//         }
//         "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": 30}
//         }
//         "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": 5}
//     }]
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/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/{+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.\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/1.13.7 gdcl/20200203")
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1/accounts")
	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/1.13.7 gdcl/20200203")
	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/1.13.7 gdcl/20200203")
	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"
	//   }
	// }

}
