// 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 3-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/20200923")
	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/20200923")
	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/20200923")
	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/20200923")
	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/20200923")
	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"
	//   ]
	// }

}
