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

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	opts = append(opts, internaloption.WithDefaultMTLSEndpoint(mtlsBasePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.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.
type GoogleAdsHomeservicesLocalservicesV1AccountReport struct {
	// AccountId: Unique identifier of the GLS account.
	AccountId int64 `json:"accountId,omitempty,string"`

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

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

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

	// 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.
	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 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 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 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 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 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 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 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.
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
// year. Must be from 1 to 12, or 0 if specifying 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 date.
// Must be from 1 to 9999, or 0 if specifying 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
// 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.
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 year. Must be from 1 to 12, or 0 if specifying 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
// date. Must be from 1 to 9999, or 0 if specifying 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/20200926")
	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 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.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying 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 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.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/accountReports:search",
	//   "response": {
	//     "$ref": "GoogleAdsHomeservicesLocalservicesV1SearchAccountReportsResponse"
	//   }
	// }

}

// 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 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.
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
// year. Must be from 1 to 12, or 0 if specifying 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 date.
// Must be from 1 to 9999, or 0 if specifying 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
// 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.
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 year. Must be from 1 to 12, or 0 if specifying 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
// date. Must be from 1 to 9999, or 0 if specifying 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/20200926")
	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 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.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "endDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying 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 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.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.month": {
	//       "description": "Month of year. Must be from 1 to 12, or 0 if specifying a year without a month and day.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "startDate.year": {
	//       "description": "Year of date. Must be from 1 to 9999, or 0 if specifying a date without a year.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "v1/detailedLeadReports:search",
	//   "response": {
	//     "$ref": "GoogleAdsHomeservicesLocalservicesV1SearchDetailedLeadReportsResponse"
	//   }
	// }

}

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