// 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 billingbudgets provides access to the Cloud Billing Budget API.
//
// For product documentation, see: https://cloud.google.com/billing/docs/how-to/budget-api-overview
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/billingbudgets/v1beta1"
//   ...
//   ctx := context.Background()
//   billingbudgetsService, err := billingbudgets.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
//
// By default, all available scopes (see "Constants") are used to authenticate. To restrict scopes, use option.WithScopes:
//
//   billingbudgetsService, err := billingbudgets.NewService(ctx, option.WithScopes(billingbudgets.CloudPlatformScope))
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   billingbudgetsService, err := billingbudgets.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, ...)
//   billingbudgetsService, err := billingbudgets.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package billingbudgets // import "google.golang.org/api/billingbudgets/v1beta1"

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 = "billingbudgets:v1beta1"
const apiName = "billingbudgets"
const apiVersion = "v1beta1"
const basePath = "https://billingbudgets.googleapis.com/"
const mtlsBasePath = "https://billingbudgets.mtls.googleapis.com/"

// OAuth2 scopes used by this API.
const (
	// View and manage your Google Cloud Platform billing accounts
	CloudBillingScope = "https://www.googleapis.com/auth/cloud-billing"

	// View and manage your data across Google Cloud Platform services
	CloudPlatformScope = "https://www.googleapis.com/auth/cloud-platform"
)

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

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

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

	BillingAccounts *BillingAccountsService
}

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

func NewBillingAccountsService(s *Service) *BillingAccountsService {
	rs := &BillingAccountsService{s: s}
	rs.Budgets = NewBillingAccountsBudgetsService(s)
	return rs
}

type BillingAccountsService struct {
	s *Service

	Budgets *BillingAccountsBudgetsService
}

func NewBillingAccountsBudgetsService(s *Service) *BillingAccountsBudgetsService {
	rs := &BillingAccountsBudgetsService{s: s}
	return rs
}

type BillingAccountsBudgetsService struct {
	s *Service
}

// GoogleCloudBillingBudgetsV1beta1AllUpdatesRule: AllUpdatesRule
// defines notifications that are sent based on budget spend and
// thresholds.
type GoogleCloudBillingBudgetsV1beta1AllUpdatesRule struct {
	// DisableDefaultIamRecipients: Optional. When set to true, disables
	// default notifications sent when a threshold is exceeded. Default
	// notifications are sent to those with Billing Account Administrator
	// and Billing Account User IAM roles for the target account.
	DisableDefaultIamRecipients bool `json:"disableDefaultIamRecipients,omitempty"`

	// MonitoringNotificationChannels: Optional. Targets to send
	// notifications to when a threshold is exceeded. This is in addition to
	// default recipients who have billing account IAM roles. The value is
	// the full REST resource name of a monitoring notification channel with
	// the form `projects/{project_id}/notificationChannels/{channel_id}`. A
	// maximum of 5 channels are allowed. See
	// https://cloud.google.com/billing/docs/how-to/budgets-notification-recipients for more
	// details.
	MonitoringNotificationChannels []string `json:"monitoringNotificationChannels,omitempty"`

	// PubsubTopic: Optional. The name of the Pub/Sub topic where budget
	// related messages will be published, in the form
	// `projects/{project_id}/topics/{topic_id}`. Updates are sent at
	// regular intervals to the topic. The topic needs to be created before
	// the budget is created; see
	// https://cloud.google.com/billing/docs/how-to/budgets#manage-notifications for more details. Caller is expected to have `pubsub.topics.setIamPolicy` permission on the topic when it's set for a budget, otherwise, the API call will fail with PERMISSION_DENIED. See https://cloud.google.com/billing/docs/how-to/budgets-programmatic-notifications for more details on Pub/Sub roles and
	// permissions.
	PubsubTopic string `json:"pubsubTopic,omitempty"`

	// SchemaVersion: Optional. The schema version of the notification sent
	// to `pubsub_topic`. Only "1.0" is accepted. It represents the JSON
	// schema as defined in
	// https://cloud.google.com/billing/docs/how-to/budgets-programmatic-notifications#notification_format
	SchemaVersion string `json:"schemaVersion,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DisableDefaultIamRecipients") 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.
	// "DisableDefaultIamRecipients") 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 *GoogleCloudBillingBudgetsV1beta1AllUpdatesRule) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1AllUpdatesRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1Budget: A budget is a plan that
// describes what you expect to spend on Cloud projects, plus the rules
// to execute as spend is tracked against that plan, (for example, send
// an alert when 90% of the target spend is met). Currently all plans
// are monthly budgets so the usage period(s) tracked are implied
// (calendar months of usage back-to-back).
type GoogleCloudBillingBudgetsV1beta1Budget struct {
	// AllUpdatesRule: Optional. Rules to apply to notifications sent based
	// on budget spend and thresholds.
	AllUpdatesRule *GoogleCloudBillingBudgetsV1beta1AllUpdatesRule `json:"allUpdatesRule,omitempty"`

	// Amount: Required. Budgeted amount.
	Amount *GoogleCloudBillingBudgetsV1beta1BudgetAmount `json:"amount,omitempty"`

	// BudgetFilter: Optional. Filters that define which resources are used
	// to compute the actual spend against the budget.
	BudgetFilter *GoogleCloudBillingBudgetsV1beta1Filter `json:"budgetFilter,omitempty"`

	// DisplayName: User data for display name in UI. Validation: <= 60
	// chars.
	DisplayName string `json:"displayName,omitempty"`

	// Etag: Optional. Etag to validate that the object is unchanged for a
	// read-modify-write operation. An empty etag will cause an update to
	// overwrite other changes.
	Etag string `json:"etag,omitempty"`

	// Name: Output only. Resource name of the budget. The resource name
	// implies the scope of a budget. Values are of the form
	// `billingAccounts/{billingAccountId}/budgets/{budgetId}`.
	Name string `json:"name,omitempty"`

	// ThresholdRules: Optional. Rules that trigger alerts (notifications of
	// thresholds being crossed) when spend exceeds the specified
	// percentages of the budget.
	ThresholdRules []*GoogleCloudBillingBudgetsV1beta1ThresholdRule `json:"thresholdRules,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AllUpdatesRule") 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. "AllUpdatesRule") 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 *GoogleCloudBillingBudgetsV1beta1Budget) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1Budget
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1BudgetAmount: The budgeted amount for
// each usage period.
type GoogleCloudBillingBudgetsV1beta1BudgetAmount struct {
	// LastPeriodAmount: Use the last period's actual spend as the budget
	// for the present period.
	LastPeriodAmount *GoogleCloudBillingBudgetsV1beta1LastPeriodAmount `json:"lastPeriodAmount,omitempty"`

	// SpecifiedAmount: A specified amount to use as the budget.
	// `currency_code` is optional. If specified, it must match the currency
	// of the billing account. The `currency_code` is provided on output.
	SpecifiedAmount *GoogleTypeMoney `json:"specifiedAmount,omitempty"`

	// ForceSendFields is a list of field names (e.g. "LastPeriodAmount") 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. "LastPeriodAmount") 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 *GoogleCloudBillingBudgetsV1beta1BudgetAmount) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1BudgetAmount
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest: Request for
// CreateBudget
type GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest struct {
	// Budget: Required. Budget to create.
	Budget *GoogleCloudBillingBudgetsV1beta1Budget `json:"budget,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Budget") 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. "Budget") 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 *GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1Filter: A filter for a budget,
// limiting the scope of the cost to calculate.
type GoogleCloudBillingBudgetsV1beta1Filter struct {
	// CreditTypesTreatment: Optional. If not set, default behavior is
	// `INCLUDE_ALL_CREDITS`.
	//
	// Possible values:
	//   "CREDIT_TYPES_TREATMENT_UNSPECIFIED"
	//   "INCLUDE_ALL_CREDITS" - All types of credit are subtracted from the
	// gross cost to determine the spend for threshold calculations.
	//   "EXCLUDE_ALL_CREDITS" - All types of credit are added to the net
	// cost to determine the spend for threshold calculations.
	CreditTypesTreatment string `json:"creditTypesTreatment,omitempty"`

	// Labels: Optional. A single label and value pair specifying that usage
	// from only this set of labeled resources should be included in the
	// budget. Currently, multiple entries or multiple values per entry are
	// not allowed. If omitted, the report will include all labeled and
	// unlabeled usage.
	Labels map[string][]interface{} `json:"labels,omitempty"`

	// Projects: Optional. A set of projects of the form
	// `projects/{project}`, specifying that usage from only this set of
	// projects should be included in the budget. If omitted, the report
	// will include all usage for the billing account, regardless of which
	// project the usage occurred on. Only zero or one project can be
	// specified currently.
	Projects []string `json:"projects,omitempty"`

	// Services: Optional. A set of services of the form
	// `services/{service_id}`, specifying that usage from only this set of
	// services should be included in the budget. If omitted, the report
	// will include usage for all the services. The service names are
	// available through the Catalog API:
	// https://cloud.google.com/billing/v1/how-tos/catalog-api.
	Services []string `json:"services,omitempty"`

	// Subaccounts: Optional. A set of subaccounts of the form
	// `billingAccounts/{account_id}`, specifying that usage from only this
	// set of subaccounts should be included in the budget. If a subaccount
	// is set to the name of the parent account, usage from the parent
	// account will be included. If omitted, the report will include usage
	// from the parent account and all subaccounts, if they exist.
	Subaccounts []string `json:"subaccounts,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "CreditTypesTreatment") 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. "CreditTypesTreatment") 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 *GoogleCloudBillingBudgetsV1beta1Filter) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1Filter
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1LastPeriodAmount: Describes a budget
// amount targeted to last period's spend. At this time, the amount is
// automatically 100% of last period's spend; that is, there are no
// other options yet. Future configuration will be described here (for
// example, configuring a percentage of last period's spend).
type GoogleCloudBillingBudgetsV1beta1LastPeriodAmount struct {
}

// GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse: Response for
// ListBudgets
type GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse struct {
	// Budgets: List of the budgets owned by the requested billing account.
	Budgets []*GoogleCloudBillingBudgetsV1beta1Budget `json:"budgets,omitempty"`

	// NextPageToken: If not empty, indicates that there may be more budgets
	// that match the request; this value should be passed in a new
	// `ListBudgetsRequest`.
	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. "Budgets") 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. "Budgets") 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 *GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleCloudBillingBudgetsV1beta1ThresholdRule: ThresholdRule contains
// a definition of a threshold which triggers an alert (a notification
// of a threshold being crossed) to be sent when spend goes above the
// specified amount. Alerts are automatically e-mailed to users with the
// Billing Account Administrator role or the Billing Account User role.
// The thresholds here have no effect on notifications sent to anything
// configured under `Budget.all_updates_rule`.
type GoogleCloudBillingBudgetsV1beta1ThresholdRule struct {
	// SpendBasis: Optional. The type of basis used to determine if spend
	// has passed the threshold. Behavior defaults to CURRENT_SPEND if not
	// set.
	//
	// Possible values:
	//   "BASIS_UNSPECIFIED" - Unspecified threshold basis.
	//   "CURRENT_SPEND" - Use current spend as the basis for comparison
	// against the threshold.
	//   "FORECASTED_SPEND" - Use forecasted spend for the period as the
	// basis for comparison against the threshold.
	SpendBasis string `json:"spendBasis,omitempty"`

	// ThresholdPercent: Required. Send an alert when this threshold is
	// exceeded. This is a 1.0-based percentage, so 0.5 = 50%. Validation:
	// non-negative number.
	ThresholdPercent float64 `json:"thresholdPercent,omitempty"`

	// ForceSendFields is a list of field names (e.g. "SpendBasis") 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. "SpendBasis") 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 *GoogleCloudBillingBudgetsV1beta1ThresholdRule) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1ThresholdRule
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

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

// GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest: Request for
// UpdateBudget
type GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest struct {
	// Budget: Required. The updated budget object. The budget to update is
	// specified by the budget name in the budget.
	Budget *GoogleCloudBillingBudgetsV1beta1Budget `json:"budget,omitempty"`

	// UpdateMask: Optional. Indicates which fields in the provided budget
	// to update. Read-only fields (such as `name`) cannot be changed. If
	// this is not provided, then only fields with non-default values from
	// the request are updated. See
	// https://developers.google.com/protocol-buffers/docs/proto3#default
	// for more details about default values.
	UpdateMask string `json:"updateMask,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Budget") 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. "Budget") 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 *GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest) MarshalJSON() ([]byte, error) {
	type NoMethod GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// GoogleProtobufEmpty: A generic empty message that you can re-use to
// avoid defining duplicated empty messages in your APIs. A typical
// example is to use it as the request or the response type of an API
// method. For instance: service Foo { rpc Bar(google.protobuf.Empty)
// returns (google.protobuf.Empty); } The JSON representation for
// `Empty` is empty JSON object `{}`.
type GoogleProtobufEmpty struct {
	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`
}

// GoogleTypeMoney: Represents an amount of money with its currency
// type.
type GoogleTypeMoney struct {
	// CurrencyCode: The three-letter currency code defined in ISO 4217.
	CurrencyCode string `json:"currencyCode,omitempty"`

	// Nanos: Number of nano (10^-9) units of the amount. The value must be
	// between -999,999,999 and +999,999,999 inclusive. If `units` is
	// positive, `nanos` must be positive or zero. If `units` is zero,
	// `nanos` can be positive, zero, or negative. If `units` is negative,
	// `nanos` must be negative or zero. For example $-1.75 is represented
	// as `units`=-1 and `nanos`=-750,000,000.
	Nanos int64 `json:"nanos,omitempty"`

	// Units: The whole units of the amount. For example if `currencyCode`
	// is "USD", then 1 unit is one US dollar.
	Units int64 `json:"units,omitempty,string"`

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

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

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

// method id "billingbudgets.billingAccounts.budgets.create":

type BillingAccountsBudgetsCreateCall struct {
	s                                                   *Service
	parent                                              string
	googlecloudbillingbudgetsv1beta1createbudgetrequest *GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest
	urlParams_                                          gensupport.URLParams
	ctx_                                                context.Context
	header_                                             http.Header
}

// Create: Creates a new budget. See Quotas and limits for more
// information on the limits of the number of budgets you can create.
func (r *BillingAccountsBudgetsService) Create(parent string, googlecloudbillingbudgetsv1beta1createbudgetrequest *GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest) *BillingAccountsBudgetsCreateCall {
	c := &BillingAccountsBudgetsCreateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	c.googlecloudbillingbudgetsv1beta1createbudgetrequest = googlecloudbillingbudgetsv1beta1createbudgetrequest
	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 *BillingAccountsBudgetsCreateCall) Fields(s ...googleapi.Field) *BillingAccountsBudgetsCreateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BillingAccountsBudgetsCreateCall) Context(ctx context.Context) *BillingAccountsBudgetsCreateCall {
	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 *BillingAccountsBudgetsCreateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BillingAccountsBudgetsCreateCall) 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())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudbillingbudgetsv1beta1createbudgetrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+parent}/budgets")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "billingbudgets.billingAccounts.budgets.create" call.
// Exactly one of *GoogleCloudBillingBudgetsV1beta1Budget or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudBillingBudgetsV1beta1Budget.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 *BillingAccountsBudgetsCreateCall) Do(opts ...googleapi.CallOption) (*GoogleCloudBillingBudgetsV1beta1Budget, 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 := &GoogleCloudBillingBudgetsV1beta1Budget{
		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": "Creates a new budget. See Quotas and limits for more information on the limits of the number of budgets you can create.",
	//   "flatPath": "v1beta1/billingAccounts/{billingAccountsId}/budgets",
	//   "httpMethod": "POST",
	//   "id": "billingbudgets.billingAccounts.budgets.create",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "parent": {
	//       "description": "Required. The name of the billing account to create the budget in. Values are of the form `billingAccounts/{billingAccountId}`.",
	//       "location": "path",
	//       "pattern": "^billingAccounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/budgets",
	//   "request": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1CreateBudgetRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1Budget"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-billing",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "billingbudgets.billingAccounts.budgets.delete":

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

// Delete: Deletes a budget. Returns successfully if already deleted.
func (r *BillingAccountsBudgetsService) Delete(name string) *BillingAccountsBudgetsDeleteCall {
	c := &BillingAccountsBudgetsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BillingAccountsBudgetsDeleteCall) Fields(s ...googleapi.Field) *BillingAccountsBudgetsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BillingAccountsBudgetsDeleteCall) Context(ctx context.Context) *BillingAccountsBudgetsDeleteCall {
	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 *BillingAccountsBudgetsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BillingAccountsBudgetsDeleteCall) 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())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "billingbudgets.billingAccounts.budgets.delete" call.
// Exactly one of *GoogleProtobufEmpty or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *GoogleProtobufEmpty.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 *BillingAccountsBudgetsDeleteCall) Do(opts ...googleapi.CallOption) (*GoogleProtobufEmpty, 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 := &GoogleProtobufEmpty{
		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": "Deletes a budget. Returns successfully if already deleted.",
	//   "flatPath": "v1beta1/billingAccounts/{billingAccountsId}/budgets/{budgetsId}",
	//   "httpMethod": "DELETE",
	//   "id": "billingbudgets.billingAccounts.budgets.delete",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of the budget to delete. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`.",
	//       "location": "path",
	//       "pattern": "^billingAccounts/[^/]+/budgets/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "GoogleProtobufEmpty"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-billing",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "billingbudgets.billingAccounts.budgets.get":

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

// Get: Returns a budget. WARNING: There are some fields exposed on the
// Google Cloud Console that aren't available on this API. When reading
// from the API, you will not see these fields in the return value,
// though they may have been set in the Cloud Console.
func (r *BillingAccountsBudgetsService) Get(name string) *BillingAccountsBudgetsGetCall {
	c := &BillingAccountsBudgetsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	return c
}

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

func (c *BillingAccountsBudgetsGetCall) 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, "v1beta1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "billingbudgets.billingAccounts.budgets.get" call.
// Exactly one of *GoogleCloudBillingBudgetsV1beta1Budget or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudBillingBudgetsV1beta1Budget.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 *BillingAccountsBudgetsGetCall) Do(opts ...googleapi.CallOption) (*GoogleCloudBillingBudgetsV1beta1Budget, 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 := &GoogleCloudBillingBudgetsV1beta1Budget{
		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": "Returns a budget. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. When reading from the API, you will not see these fields in the return value, though they may have been set in the Cloud Console.",
	//   "flatPath": "v1beta1/billingAccounts/{billingAccountsId}/budgets/{budgetsId}",
	//   "httpMethod": "GET",
	//   "id": "billingbudgets.billingAccounts.budgets.get",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Required. Name of budget to get. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`.",
	//       "location": "path",
	//       "pattern": "^billingAccounts/[^/]+/budgets/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "response": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1Budget"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-billing",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// method id "billingbudgets.billingAccounts.budgets.list":

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

// List: Returns a list of budgets for a billing account. WARNING: There
// are some fields exposed on the Google Cloud Console that aren't
// available on this API. When reading from the API, you will not see
// these fields in the return value, though they may have been set in
// the Cloud Console.
func (r *BillingAccountsBudgetsService) List(parent string) *BillingAccountsBudgetsListCall {
	c := &BillingAccountsBudgetsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.parent = parent
	return c
}

// PageSize sets the optional parameter "pageSize": The maximum number
// of budgets to return per page. The default and maximum value are 100.
func (c *BillingAccountsBudgetsListCall) PageSize(pageSize int64) *BillingAccountsBudgetsListCall {
	c.urlParams_.Set("pageSize", fmt.Sprint(pageSize))
	return c
}

// PageToken sets the optional parameter "pageToken": The value returned
// by the last `ListBudgetsResponse` which indicates that this is a
// continuation of a prior `ListBudgets` call, and that the system
// should return the next page of data.
func (c *BillingAccountsBudgetsListCall) PageToken(pageToken string) *BillingAccountsBudgetsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

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

func (c *BillingAccountsBudgetsListCall) 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, "v1beta1/{+parent}/budgets")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"parent": c.parent,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "billingbudgets.billingAccounts.budgets.list" call.
// Exactly one of *GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse
// or error will be non-nil. Any non-2xx status code is an error.
// Response headers are in either
// *GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse.ServerResponse.He
// ader 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 *BillingAccountsBudgetsListCall) Do(opts ...googleapi.CallOption) (*GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse, 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 := &GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse{
		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": "Returns a list of budgets for a billing account. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. When reading from the API, you will not see these fields in the return value, though they may have been set in the Cloud Console.",
	//   "flatPath": "v1beta1/billingAccounts/{billingAccountsId}/budgets",
	//   "httpMethod": "GET",
	//   "id": "billingbudgets.billingAccounts.budgets.list",
	//   "parameterOrder": [
	//     "parent"
	//   ],
	//   "parameters": {
	//     "pageSize": {
	//       "description": "Optional. The maximum number of budgets to return per page. The default and maximum value are 100.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Optional. The value returned by the last `ListBudgetsResponse` which indicates that this is a continuation of a prior `ListBudgets` call, and that the system should return the next page of data.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parent": {
	//       "description": "Required. Name of billing account to list budgets under. Values are of the form `billingAccounts/{billingAccountId}`.",
	//       "location": "path",
	//       "pattern": "^billingAccounts/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+parent}/budgets",
	//   "response": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-billing",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}

// 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 *BillingAccountsBudgetsListCall) Pages(ctx context.Context, f func(*GoogleCloudBillingBudgetsV1beta1ListBudgetsResponse) 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 "billingbudgets.billingAccounts.budgets.patch":

type BillingAccountsBudgetsPatchCall struct {
	s                                                   *Service
	name                                                string
	googlecloudbillingbudgetsv1beta1updatebudgetrequest *GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest
	urlParams_                                          gensupport.URLParams
	ctx_                                                context.Context
	header_                                             http.Header
}

// Patch: Updates a budget and returns the updated budget. WARNING:
// There are some fields exposed on the Google Cloud Console that aren't
// available on this API. Budget fields that are not exposed in this API
// will not be changed by this method.
func (r *BillingAccountsBudgetsService) Patch(name string, googlecloudbillingbudgetsv1beta1updatebudgetrequest *GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest) *BillingAccountsBudgetsPatchCall {
	c := &BillingAccountsBudgetsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.name = name
	c.googlecloudbillingbudgetsv1beta1updatebudgetrequest = googlecloudbillingbudgetsv1beta1updatebudgetrequest
	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 *BillingAccountsBudgetsPatchCall) Fields(s ...googleapi.Field) *BillingAccountsBudgetsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BillingAccountsBudgetsPatchCall) Context(ctx context.Context) *BillingAccountsBudgetsPatchCall {
	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 *BillingAccountsBudgetsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BillingAccountsBudgetsPatchCall) 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())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.googlecloudbillingbudgetsv1beta1updatebudgetrequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "v1beta1/{+name}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"name": c.name,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "billingbudgets.billingAccounts.budgets.patch" call.
// Exactly one of *GoogleCloudBillingBudgetsV1beta1Budget or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *GoogleCloudBillingBudgetsV1beta1Budget.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 *BillingAccountsBudgetsPatchCall) Do(opts ...googleapi.CallOption) (*GoogleCloudBillingBudgetsV1beta1Budget, 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 := &GoogleCloudBillingBudgetsV1beta1Budget{
		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": "Updates a budget and returns the updated budget. WARNING: There are some fields exposed on the Google Cloud Console that aren't available on this API. Budget fields that are not exposed in this API will not be changed by this method.",
	//   "flatPath": "v1beta1/billingAccounts/{billingAccountsId}/budgets/{budgetsId}",
	//   "httpMethod": "PATCH",
	//   "id": "billingbudgets.billingAccounts.budgets.patch",
	//   "parameterOrder": [
	//     "name"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Output only. Resource name of the budget. The resource name implies the scope of a budget. Values are of the form `billingAccounts/{billingAccountId}/budgets/{budgetId}`.",
	//       "location": "path",
	//       "pattern": "^billingAccounts/[^/]+/budgets/[^/]+$",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "v1beta1/{+name}",
	//   "request": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1UpdateBudgetRequest"
	//   },
	//   "response": {
	//     "$ref": "GoogleCloudBillingBudgetsV1beta1Budget"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/cloud-billing",
	//     "https://www.googleapis.com/auth/cloud-platform"
	//   ]
	// }

}
