// Copyright 2022 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 localservices provides access to the Local Services API.
//
// For product documentation, see: https://ads.google.com/local-services-ads/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/localservices/v1"
//   ...
//   ctx := context.Background()
//   localservicesService, err := localservices.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:
//
//   localservicesService, err := localservices.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, ...)
//   localservicesService, err := localservices.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package localservices // import "google.golang.org/api/localservices/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	internal "google.golang.org/api/internal"
	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 = "localservices:v1"
const apiName = "localservices"
const apiVersion = "v1"
const basePath = "https://localservices.googleapis.com/"
const mtlsBasePath = "https://localservices.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// Manage your AdWords campaigns
	AdwordsScope = "https://www.googleapis.com/auth/adwords"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := internaloption.WithDefaultScopes(
		"https://www.googleapis.com/auth/adwords",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.AccountReports = NewAccountReportsService(s)
	s.DetailedLeadReports = NewDetailedLeadReportsService(s)
	return s, nil
}

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

	AccountReports *AccountReportsService

	DetailedLeadReports *DetailedLeadReportsService
}

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

func NewAccountReportsService(s *Service) *AccountReportsService {
	rs := &AccountReportsService{s: s}
	return rs
}

type AccountReportsService struct {
	s *Service
}

func NewDetailedLeadReportsService(s *Service) *DetailedLeadReportsService {
	rs := &DetailedLeadReportsService{s: s}
	return rs
}

type DetailedLeadReportsService struct {
	s *Service
}

// GoogleAdsHomeservicesLocalservicesV1AccountReport: An Account Report
// of a GLS account identified by their account id containing aggregate
// data gathered from a particular date range. Next ID: 18
type GoogleAdsHomeservicesLocalservicesV1AccountReport struct {
	// AccountId: Unique identifier of the GLS account.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AggregatorInfo: Aggregator specific information related to the
	// account.
	AggregatorInfo *GoogleAdsHomeservicesLocalservicesV1AggregatorInfo `json:"aggregatorInfo,omitempty"`

	// AverageFiveStarRating: Average review rating score from 1-5 stars.
	AverageFiveStarRating float64 `json:"averageFiveStarRating,omitempty"`

	// AverageWeeklyBudget: Average weekly budget in the currency code of
	// the account.
	AverageWeeklyBudget float64 `json:"averageWeeklyBudget,omitempty"`

	// BusinessName: Business name of the account.
	BusinessName string `json:"businessName,omitempty"`

	// CurrencyCode: Currency code of the account.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// CurrentPeriodChargedLeads: Number of charged leads the account
	// received in current specified period.
	CurrentPeriodChargedLeads int64 `json:"currentPeriodChargedLeads,omitempty,string"`

	// CurrentPeriodConnectedPhoneCalls: Number of connected phone calls
	// (duration over 30s) in current specified period.
	CurrentPeriodConnectedPhoneCalls int64 `json:"currentPeriodConnectedPhoneCalls,omitempty,string"`

	// CurrentPeriodPhoneCalls: Number of phone calls in current specified
	// period, including both connected and unconnected calls.
	CurrentPeriodPhoneCalls int64 `json:"currentPeriodPhoneCalls,omitempty,string"`

	// CurrentPeriodTotalCost: Total cost of the account in current
	// specified period in the account's specified currency.
	CurrentPeriodTotalCost float64 `json:"currentPeriodTotalCost,omitempty"`

	// ImpressionsLastTwoDays: Number of impressions that customers have had
	// in the past 2 days.
	ImpressionsLastTwoDays int64 `json:"impressionsLastTwoDays,omitempty,string"`

	// PhoneLeadResponsiveness: Phone lead responsiveness of the account for
	// the past 90 days from current date. This is computed by taking the
	// total number of connected calls from charged phone leads and dividing
	// by the total number of calls received.
	PhoneLeadResponsiveness float64 `json:"phoneLeadResponsiveness,omitempty"`

	// PreviousPeriodChargedLeads: Number of charged leads the account
	// received in previous specified period.
	PreviousPeriodChargedLeads int64 `json:"previousPeriodChargedLeads,omitempty,string"`

	// PreviousPeriodConnectedPhoneCalls: Number of connected phone calls
	// (duration over 30s) in previous specified period.
	PreviousPeriodConnectedPhoneCalls int64 `json:"previousPeriodConnectedPhoneCalls,omitempty,string"`

	// PreviousPeriodPhoneCalls: Number of phone calls in previous specified
	// period, including both connected and unconnected calls.
	PreviousPeriodPhoneCalls int64 `json:"previousPeriodPhoneCalls,omitempty,string"`

	// PreviousPeriodTotalCost: Total cost of the account in previous
	// specified period in the account's specified currency.
	PreviousPeriodTotalCost float64 `json:"previousPeriodTotalCost,omitempty"`

	// TotalReview: Total number of reviews the account has up to current
	// date.
	TotalReview int64 `json:"totalReview,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default 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. "AccountId") 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 *GoogleAdsHomeservicesLocalservicesV1AccountReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1AccountReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

func (s *GoogleAdsHomeservicesLocalservicesV1AccountReport) UnmarshalJSON(data []byte) error {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1AccountReport
	var s1 struct {
		AverageFiveStarRating   gensupport.JSONFloat64 `json:"averageFiveStarRating"`
		AverageWeeklyBudget     gensupport.JSONFloat64 `json:"averageWeeklyBudget"`
		CurrentPeriodTotalCost  gensupport.JSONFloat64 `json:"currentPeriodTotalCost"`
		PhoneLeadResponsiveness gensupport.JSONFloat64 `json:"phoneLeadResponsiveness"`
		PreviousPeriodTotalCost gensupport.JSONFloat64 `json:"previousPeriodTotalCost"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.AverageFiveStarRating = float64(s1.AverageFiveStarRating)
	s.AverageWeeklyBudget = float64(s1.AverageWeeklyBudget)
	s.CurrentPeriodTotalCost = float64(s1.CurrentPeriodTotalCost)
	s.PhoneLeadResponsiveness = float64(s1.PhoneLeadResponsiveness)
	s.PreviousPeriodTotalCost = float64(s1.PreviousPeriodTotalCost)
	return nil
}

// GoogleAdsHomeservicesLocalservicesV1AggregatorInfo: Conatiner for
// aggregator specific information if lead is for an aggregator GLS
// account.
type GoogleAdsHomeservicesLocalservicesV1AggregatorInfo struct {
	// AggregatorProviderId: Provider id (listed in aggregator system) which
	// maps to a account id in GLS system.
	AggregatorProviderId string `json:"aggregatorProviderId,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "AggregatorProviderId") to unconditionally include in API requests.
	// By default, fields with empty or default 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. "AggregatorProviderId") 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 *GoogleAdsHomeservicesLocalservicesV1AggregatorInfo) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1AggregatorInfo
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAdsHomeservicesLocalservicesV1BookingLead: Container for
// booking lead specific information.
type GoogleAdsHomeservicesLocalservicesV1BookingLead struct {
	// BookingAppointmentTimestamp: Timestamp of when service is provided by
	// advertiser.
	BookingAppointmentTimestamp string `json:"bookingAppointmentTimestamp,omitempty"`

	// ConsumerEmail: Consumer email associated with the booking lead.
	ConsumerEmail string `json:"consumerEmail,omitempty"`

	// ConsumerPhoneNumber: Consumer phone number associated with the
	// booking lead.
	ConsumerPhoneNumber string `json:"consumerPhoneNumber,omitempty"`

	// CustomerName: Name of the customer who created the lead.
	CustomerName string `json:"customerName,omitempty"`

	// JobType: The job type of the specified lead.
	JobType string `json:"jobType,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "BookingAppointmentTimestamp") to unconditionally include in API
	// requests. By default, fields with empty or default 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.
	// "BookingAppointmentTimestamp") 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 *GoogleAdsHomeservicesLocalservicesV1BookingLead) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1BookingLead
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAdsHomeservicesLocalservicesV1DetailedLeadReport: A Detailed
// Lead Report of a lead identified by their lead id and contains
// consumer, account, monetization, and lead data.
type GoogleAdsHomeservicesLocalservicesV1DetailedLeadReport struct {
	// AccountId: Identifies account that received the lead.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AggregatorInfo: Aggregator specific information related to the lead.
	AggregatorInfo *GoogleAdsHomeservicesLocalservicesV1AggregatorInfo `json:"aggregatorInfo,omitempty"`

	// BookingLead: More information associated to only booking leads.
	BookingLead *GoogleAdsHomeservicesLocalservicesV1BookingLead `json:"bookingLead,omitempty"`

	// BusinessName: Business name associated to the account.
	BusinessName string `json:"businessName,omitempty"`

	// ChargeStatus: Whether the lead has been charged.
	//
	// Possible values:
	//   "CHARGE_STATUS_UNSPECIFIED" - Not specified.
	//   "CHARGED" - Charged.
	//   "NOT_CHARGED" - Not charged.
	ChargeStatus string `json:"chargeStatus,omitempty"`

	// CurrencyCode: Currency code.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// DisputeStatus: Dispute status related to the lead.
	DisputeStatus string `json:"disputeStatus,omitempty"`

	// Geo: Location of the associated account's home city.
	Geo string `json:"geo,omitempty"`

	// LeadCategory: Lead category (e.g. hvac, plumber)
	LeadCategory string `json:"leadCategory,omitempty"`

	// LeadCreationTimestamp: Timestamp of when the lead was created.
	LeadCreationTimestamp string `json:"leadCreationTimestamp,omitempty"`

	// LeadId: Unique identifier of a Detailed Lead Report.
	LeadId int64 `json:"leadId,omitempty,string"`

	// LeadPrice: Price of the lead (available only after it has been
	// charged).
	LeadPrice float64 `json:"leadPrice,omitempty"`

	// LeadType: Lead type.
	//
	// Possible values:
	//   "LEAD_TYPE_UNSPECIFIED" - Not specified.
	//   "MESSAGE" - Message lead.
	//   "PHONE_CALL" - Phone call lead.
	//   "BOOKING" - Booking lead.
	LeadType string `json:"leadType,omitempty"`

	// MessageLead: More information associated to only message leads.
	MessageLead *GoogleAdsHomeservicesLocalservicesV1MessageLead `json:"messageLead,omitempty"`

	// PhoneLead: More information associated to only phone leads.
	PhoneLead *GoogleAdsHomeservicesLocalservicesV1PhoneLead `json:"phoneLead,omitempty"`

	// Timezone: Timezone of the particular provider associated to a lead.
	Timezone *GoogleTypeTimeZone `json:"timezone,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty or default 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. "AccountId") 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 *GoogleAdsHomeservicesLocalservicesV1DetailedLeadReport) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1DetailedLeadReport
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// GoogleAdsHomeservicesLocalservicesV1MessageLead: Container for
// message lead specific information.
type GoogleAdsHomeservicesLocalservicesV1MessageLead struct {
	// ConsumerPhoneNumber: Consumer phone number associated with the
	// message lead.
	ConsumerPhoneNumber string `json:"consumerPhoneNumber,omitempty"`

	// CustomerName: Name of the customer who created the lead.
	CustomerName string `json:"customerName,omitempty"`

	// JobType: The job type of the specified lead.
	JobType string `json:"jobType,omitempty"`

	// PostalCode: The postal code of the customer who created the lead.
	PostalCode string `json:"postalCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ConsumerPhoneNumber")
	// to unconditionally include in API requests. By default, fields with
	// empty or default 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. "ConsumerPhoneNumber") 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 *GoogleAdsHomeservicesLocalservicesV1MessageLead) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1MessageLead
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAdsHomeservicesLocalservicesV1PhoneLead: Container for phone
// lead specific information.
type GoogleAdsHomeservicesLocalservicesV1PhoneLead struct {
	// ChargedCallTimestamp: Timestamp of the phone call which resulted in a
	// charged phone lead.
	ChargedCallTimestamp string `json:"chargedCallTimestamp,omitempty"`

	// ChargedConnectedCallDurationSeconds: Duration of the charged phone
	// call in seconds.
	ChargedConnectedCallDurationSeconds string `json:"chargedConnectedCallDurationSeconds,omitempty"`

	// ConsumerPhoneNumber: Consumer phone number associated with the phone
	// lead.
	ConsumerPhoneNumber string `json:"consumerPhoneNumber,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ChargedCallTimestamp") to unconditionally include in API requests.
	// By default, fields with empty or default 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. "ChargedCallTimestamp") 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 *GoogleAdsHomeservicesLocalservicesV1PhoneLead) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1PhoneLead
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse: A
// page of the response received from the SearchAccountReports method. A
// paginated response where more pages are available has
// `next_page_token` set. This token can be used in a subsequent request
// to retrieve the next request page.
type GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse struct {
	// AccountReports: List of account reports which maps 1:1 to a
	// particular linked GLS account.
	AccountReports []*GoogleAdsHomeservicesLocalservicesV1AccountReport `json:"accountReports,omitempty"`

	// NextPageToken: Pagination token to retrieve the next page of results.
	// When `next_page_token` is not filled in, there is no next page and
	// the list returned is the last page in the result set.
	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. "AccountReports") to
	// unconditionally include in API requests. By default, fields with
	// empty or default 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. "AccountReports") 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 *GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse:
//  A page of the response received from the SearchDetailedLeadReports
// method. A paginated response where more pages are available has
// `next_page_token` set. This token can be used in a subsequent request
// to retrieve the next request page.
type GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse struct {
	// DetailedLeadReports: List of detailed lead reports uniquely
	// identified by external lead id.
	DetailedLeadReports []*GoogleAdsHomeservicesLocalservicesV1DetailedLeadReport `json:"detailedLeadReports,omitempty"`

	// NextPageToken: Pagination token to retrieve the next page of results.
	// When `next_page_token` is not filled in, there is no next page and
	// the list returned is the last page in the result set.
	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. "DetailedLeadReports")
	// to unconditionally include in API requests. By default, fields with
	// empty or default 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. "DetailedLeadReports") 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 *GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleTypeTimeZone: Represents a time zone from the IANA Time Zone
// Database (https://www.iana.org/time-zones).
type GoogleTypeTimeZone struct {
	// Id: IANA Time Zone Database time zone, e.g. "America/New_York".
	Id string `json:"id,omitempty"`

	// Version: Optional. IANA Time Zone Database version number, e.g.
	// "2019a".
	Version string `json:"version,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty or default values are omitted from API requests. However, any
	// non-pointer, non-interface field appearing in ForceSendFields will be
	// sent to the server regardless of whether the field is empty or not.
	// This may be used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

func (s *GoogleTypeTimeZone) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleTypeTimeZone
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "localservices.accountReports.search":

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

// Search: Get account reports containing aggregate account data of all
// linked GLS accounts. Caller needs to provide their manager customer
// id and the associated auth credential that allows them read
// permissions on their linked accounts.
func (r *AccountReportsService) Search() *AccountReportsSearchCall {
	c := &AccountReportsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

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

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

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

// PageSize sets the optional parameter "pageSize": The maximum number
// of accounts to return. If the page size is unset, page size will
// default to 1000. Maximum page_size is 10000.
func (c *AccountReportsSearchCall) PageSize(pageSize int64) *AccountReportsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// `next_page_token` value returned from a previous request to
// SearchAccountReports that indicates where listing should continue.
func (c *AccountReportsSearchCall) PageToken(pageToken string) *AccountReportsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": A query string for
// searching for account reports. Caller must provide a customer id of
// their MCC account with an associated Gaia Mint that allows read
// permission on their linked accounts. Search expressions are case
// insensitive. Example query: | Query | Description |
// |-------------------------|-------------------------------------------
// ----| | manager_customer_id:123 | Get Account Report for Manager with
// id 123. | Required.
func (c *AccountReportsSearchCall) Query(query string) *AccountReportsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

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

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

// StartDateYear sets the optional parameter "startDate.year": Year of
// the date. Must be from 1 to 9999, or 0 to specify a date without a
// year.
func (c *AccountReportsSearchCall) StartDateYear(startDateYear int64) *AccountReportsSearchCall {
	c.urlParams_.Set("startDate.year", fmt.Sprint(startDateYear))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountReportsSearchCall) Fields(s ...googleapi.Field) *AccountReportsSearchCall {
	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 *AccountReportsSearchCall) IfNoneMatch(entityTag string) *AccountReportsSearchCall {
	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 *AccountReportsSearchCall) Context(ctx context.Context) *AccountReportsSearchCall {
	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 *AccountReportsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountReportsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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/accountReports:search")
	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 "localservices.accountReports.search" call.
// Exactly one of
// *GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse or
// error will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse.Serv
// erResponse.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 *AccountReportsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse, 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 := &GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get account reports containing aggregate account data of all linked GLS accounts. Caller needs to provide their manager customer id and the associated auth credential that allows them read permissions on their linked accounts.",
	//   "flatPath": "v1/accountReports:search",
	//   "httpMethod": "GET",
	//   "id": "localservices.accountReports.search",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "endDate.day": {
	//       "description": "Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.month": {
	//       "description": "Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.year": {
	//       "description": "Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of accounts to return. If the page size is unset, page size will default to 1000. Maximum page_size is 10000. Optional.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The `next_page_token` value returned from a previous request to SearchAccountReports that indicates where listing should continue. Optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "A query string for searching for account reports. Caller must provide a customer id of their MCC account with an associated Gaia Mint that allows read permission on their linked accounts. Search expressions are case insensitive. Example query: | Query | Description | |-------------------------|-----------------------------------------------| | manager_customer_id:123 | Get Account Report for Manager with id 123. | Required.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "startDate.day": {
	//       "description": "Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.month": {
	//       "description": "Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.year": {
	//       "description": "Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/accountReports:search",
	//   "response": {
	//     "$ref": "GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adwords"
	//   ]
	// }

}

// 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 *AccountReportsSearchCall) Pages(ctx context.Context, f func(*GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse) 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 "localservices.detailedLeadReports.search":

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

// Search: Get detailed lead reports containing leads that have been
// received by all linked GLS accounts. Caller needs to provide their
// manager customer id and the associated auth credential that allows
// them read permissions on their linked accounts.
func (r *DetailedLeadReportsService) Search() *DetailedLeadReportsSearchCall {
	c := &DetailedLeadReportsSearchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

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

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

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

// PageSize sets the optional parameter "pageSize": The maximum number
// of accounts to return. If the page size is unset, page size will
// default to 1000. Maximum page_size is 10000.
func (c *DetailedLeadReportsSearchCall) PageSize(pageSize int64) *DetailedLeadReportsSearchCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The
// `next_page_token` value returned from a previous request to
// SearchDetailedLeadReports that indicates where listing should
// continue.
func (c *DetailedLeadReportsSearchCall) PageToken(pageToken string) *DetailedLeadReportsSearchCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Query sets the optional parameter "query": A query string for
// searching for account reports. Caller must provide a customer id of
// their MCC account with an associated Gaia Mint that allows read
// permission on their linked accounts. Search expressions are case
// insensitive. Example query: | Query | Description |
// |-------------------------|-------------------------------------------
// ----| | manager_customer_id:123 | Get Detailed Lead Report for
// Manager with id | | | 123. | Required.
func (c *DetailedLeadReportsSearchCall) Query(query string) *DetailedLeadReportsSearchCall {
	c.urlParams_.Set("query", query)
	return c
}

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

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

// StartDateYear sets the optional parameter "startDate.year": Year of
// the date. Must be from 1 to 9999, or 0 to specify a date without a
// year.
func (c *DetailedLeadReportsSearchCall) StartDateYear(startDateYear int64) *DetailedLeadReportsSearchCall {
	c.urlParams_.Set("startDate.year", fmt.Sprint(startDateYear))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DetailedLeadReportsSearchCall) Fields(s ...googleapi.Field) *DetailedLeadReportsSearchCall {
	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 *DetailedLeadReportsSearchCall) IfNoneMatch(entityTag string) *DetailedLeadReportsSearchCall {
	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 *DetailedLeadReportsSearchCall) Context(ctx context.Context) *DetailedLeadReportsSearchCall {
	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 *DetailedLeadReportsSearchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DetailedLeadReportsSearchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/"+gensupport.GoVersion()+" gdcl/"+internal.Version)
	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/detailedLeadReports:search")
	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 "localservices.detailedLeadReports.search" call.
// Exactly one of
// *GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse
//  or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse
// .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 *DetailedLeadReportsSearchCall) Do(opts ...googleapi.CallOption) (*GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse, 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 := &GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Get detailed lead reports containing leads that have been received by all linked GLS accounts. Caller needs to provide their manager customer id and the associated auth credential that allows them read permissions on their linked accounts.",
	//   "flatPath": "v1/detailedLeadReports:search",
	//   "httpMethod": "GET",
	//   "id": "localservices.detailedLeadReports.search",
	//   "parameterOrder": [],
	//   "parameters": {
	//     "endDate.day": {
	//       "description": "Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.month": {
	//       "description": "Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.year": {
	//       "description": "Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageSize": {
	//       "description": "The maximum number of accounts to return. If the page size is unset, page size will default to 1000. Maximum page_size is 10000. Optional.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The `next_page_token` value returned from a previous request to SearchDetailedLeadReports that indicates where listing should continue. Optional.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "query": {
	//       "description": "A query string for searching for account reports. Caller must provide a customer id of their MCC account with an associated Gaia Mint that allows read permission on their linked accounts. Search expressions are case insensitive. Example query: | Query | Description | |-------------------------|-----------------------------------------------| | manager_customer_id:123 | Get Detailed Lead Report for Manager with id | | | 123. | Required.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "startDate.day": {
	//       "description": "Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.month": {
	//       "description": "Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.year": {
	//       "description": "Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/detailedLeadReports:search",
	//   "response": {
	//     "$ref": "GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/adwords"
	//   ]
	// }

}

// 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 *DetailedLeadReportsSearchCall) Pages(ctx context.Context, f func(*GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse) 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)
	}
}
