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

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

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

}

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

}

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