// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Code generated by protoc-gen-go_gapic. DO NOT EDIT.

package functions

import (
	"context"
	"fmt"
	"math"
	"net/url"
	"time"

	"cloud.google.com/go/longrunning"
	lroauto "cloud.google.com/go/longrunning/autogen"
	"github.com/golang/protobuf/proto"
	gax "github.com/googleapis/gax-go/v2"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	"google.golang.org/api/option/internaloption"
	gtransport "google.golang.org/api/transport/grpc"
	functionspb "google.golang.org/genproto/googleapis/cloud/functions/v1"
	iampb "google.golang.org/genproto/googleapis/iam/v1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var newCloudFunctionsClientHook clientHook

// CloudFunctionsCallOptions contains the retry settings for each method of CloudFunctionsClient.
type CloudFunctionsCallOptions struct {
	ListFunctions       []gax.CallOption
	GetFunction         []gax.CallOption
	CreateFunction      []gax.CallOption
	UpdateFunction      []gax.CallOption
	DeleteFunction      []gax.CallOption
	CallFunction        []gax.CallOption
	GenerateUploadUrl   []gax.CallOption
	GenerateDownloadUrl []gax.CallOption
	SetIamPolicy        []gax.CallOption
	GetIamPolicy        []gax.CallOption
	TestIamPermissions  []gax.CallOption
}

func defaultCloudFunctionsClientOptions() []option.ClientOption {
	return []option.ClientOption{
		internaloption.WithDefaultEndpoint("cloudfunctions.googleapis.com:443"),
		internaloption.WithDefaultMTLSEndpoint("cloudfunctions.mtls.googleapis.com:443"),
		option.WithGRPCDialOption(grpc.WithDisableServiceConfig()),
		option.WithScopes(DefaultAuthScopes()...),
		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
	}
}

func defaultCloudFunctionsCallOptions() *CloudFunctionsCallOptions {
	return &CloudFunctionsCallOptions{
		ListFunctions:       []gax.CallOption{},
		GetFunction:         []gax.CallOption{},
		CreateFunction:      []gax.CallOption{},
		UpdateFunction:      []gax.CallOption{},
		DeleteFunction:      []gax.CallOption{},
		CallFunction:        []gax.CallOption{},
		GenerateUploadUrl:   []gax.CallOption{},
		GenerateDownloadUrl: []gax.CallOption{},
		SetIamPolicy:        []gax.CallOption{},
		GetIamPolicy:        []gax.CallOption{},
		TestIamPermissions:  []gax.CallOption{},
	}
}

// CloudFunctionsClient is a client for interacting with .
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type CloudFunctionsClient struct {
	// Connection pool of gRPC connections to the service.
	connPool gtransport.ConnPool

	// flag to opt out of default deadlines via GOOGLE_API_GO_EXPERIMENTAL_DISABLE_DEFAULT_DEADLINE
	disableDeadlines bool

	// The gRPC API client.
	cloudFunctionsClient functionspb.CloudFunctionsServiceClient

	// LROClient is used internally to handle longrunning operations.
	// It is exposed so that its CallOptions can be modified if required.
	// Users should not Close this client.
	LROClient *lroauto.OperationsClient

	// The call options for this service.
	CallOptions *CloudFunctionsCallOptions

	// The x-goog-* metadata to be sent with each request.
	xGoogMetadata metadata.MD
}

// NewCloudFunctionsClient creates a new cloud functions service client.
//
// A service that application uses to manipulate triggers and functions.
func NewCloudFunctionsClient(ctx context.Context, opts ...option.ClientOption) (*CloudFunctionsClient, error) {
	clientOpts := defaultCloudFunctionsClientOptions()

	if newCloudFunctionsClientHook != nil {
		hookOpts, err := newCloudFunctionsClientHook(ctx, clientHookParams{})
		if err != nil {
			return nil, err
		}
		clientOpts = append(clientOpts, hookOpts...)
	}

	disableDeadlines, err := checkDisableDeadlines()
	if err != nil {
		return nil, err
	}

	connPool, err := gtransport.DialPool(ctx, append(clientOpts, opts...)...)
	if err != nil {
		return nil, err
	}
	c := &CloudFunctionsClient{
		connPool:         connPool,
		disableDeadlines: disableDeadlines,
		CallOptions:      defaultCloudFunctionsCallOptions(),

		cloudFunctionsClient: functionspb.NewCloudFunctionsServiceClient(connPool),
	}
	c.setGoogleClientInfo()

	c.LROClient, err = lroauto.NewOperationsClient(ctx, gtransport.WithConnPool(connPool))
	if err != nil {
		// This error "should not happen", since we are just reusing old connection pool
		// and never actually need to dial.
		// If this does happen, we could leak connp. However, we cannot close conn:
		// If the user invoked the constructor with option.WithGRPCConn,
		// we would close a connection that's still in use.
		// TODO: investigate error conditions.
		return nil, err
	}
	return c, nil
}

// Connection returns a connection to the API service.
//
// Deprecated.
func (c *CloudFunctionsClient) Connection() *grpc.ClientConn {
	return c.connPool.Conn()
}

// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *CloudFunctionsClient) Close() error {
	return c.connPool.Close()
}

// setGoogleClientInfo sets the name and version of the application in
// the `x-goog-api-client` header passed on each request. Intended for
// use by Google-written clients.
func (c *CloudFunctionsClient) setGoogleClientInfo(keyval ...string) {
	kv := append([]string{"gl-go", versionGo()}, keyval...)
	kv = append(kv, "gapic", versionClient, "gax", gax.Version, "grpc", grpc.Version)
	c.xGoogMetadata = metadata.Pairs("x-goog-api-client", gax.XGoogHeader(kv...))
}

// ListFunctions returns a list of functions that belong to the requested project.
func (c *CloudFunctionsClient) ListFunctions(ctx context.Context, req *functionspb.ListFunctionsRequest, opts ...gax.CallOption) *CloudFunctionIterator {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ListFunctions[0:len(c.CallOptions.ListFunctions):len(c.CallOptions.ListFunctions)], opts...)
	it := &CloudFunctionIterator{}
	req = proto.Clone(req).(*functionspb.ListFunctionsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*functionspb.CloudFunction, string, error) {
		var resp *functionspb.ListFunctionsResponse
		req.PageToken = pageToken
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.cloudFunctionsClient.ListFunctions(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetFunctions(), resp.GetNextPageToken(), nil
	}
	fetch := func(pageSize int, pageToken string) (string, error) {
		items, nextPageToken, err := it.InternalFetch(pageSize, pageToken)
		if err != nil {
			return "", err
		}
		it.items = append(it.items, items...)
		return nextPageToken, nil
	}
	it.pageInfo, it.nextFunc = iterator.NewPageInfo(fetch, it.bufLen, it.takeBuf)
	it.pageInfo.MaxSize = int(req.GetPageSize())
	it.pageInfo.Token = req.GetPageToken()
	return it
}

// GetFunction returns a function with the given name from the requested project.
func (c *CloudFunctionsClient) GetFunction(ctx context.Context, req *functionspb.GetFunctionRequest, opts ...gax.CallOption) (*functionspb.CloudFunction, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetFunction[0:len(c.CallOptions.GetFunction):len(c.CallOptions.GetFunction)], opts...)
	var resp *functionspb.CloudFunction
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.GetFunction(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateFunction creates a new function. If a function with the given name already exists in
// the specified project, the long running operation will return
// ALREADY_EXISTS error.
func (c *CloudFunctionsClient) CreateFunction(ctx context.Context, req *functionspb.CreateFunctionRequest, opts ...gax.CallOption) (*CreateFunctionOperation, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "location", url.QueryEscape(req.GetLocation())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateFunction[0:len(c.CallOptions.CreateFunction):len(c.CallOptions.CreateFunction)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.CreateFunction(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &CreateFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, resp),
	}, nil
}

// UpdateFunction updates existing function.
func (c *CloudFunctionsClient) UpdateFunction(ctx context.Context, req *functionspb.UpdateFunctionRequest, opts ...gax.CallOption) (*UpdateFunctionOperation, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "function.name", url.QueryEscape(req.GetFunction().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateFunction[0:len(c.CallOptions.UpdateFunction):len(c.CallOptions.UpdateFunction)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.UpdateFunction(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &UpdateFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, resp),
	}, nil
}

// DeleteFunction deletes a function with the given name from the specified project. If the
// given function is used by some trigger, the trigger will be updated to
// remove this function.
func (c *CloudFunctionsClient) DeleteFunction(ctx context.Context, req *functionspb.DeleteFunctionRequest, opts ...gax.CallOption) (*DeleteFunctionOperation, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteFunction[0:len(c.CallOptions.DeleteFunction):len(c.CallOptions.DeleteFunction)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.DeleteFunction(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &DeleteFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, resp),
	}, nil
}

// CallFunction synchronously invokes a deployed Cloud Function. To be used for testing
// purposes as very limited traffic is allowed. For more information on
// the actual limits, refer to
// Rate Limits (at https://cloud.google.com/functions/quotas#rate_limits).
func (c *CloudFunctionsClient) CallFunction(ctx context.Context, req *functionspb.CallFunctionRequest, opts ...gax.CallOption) (*functionspb.CallFunctionResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CallFunction[0:len(c.CallOptions.CallFunction):len(c.CallOptions.CallFunction)], opts...)
	var resp *functionspb.CallFunctionResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.CallFunction(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// GenerateUploadUrl returns a signed URL for uploading a function source code.
// For more information about the signed URL usage see:
// https://cloud.google.com/storage/docs/access-control/signed-urls (at https://cloud.google.com/storage/docs/access-control/signed-urls).
// Once the function source code upload is complete, the used signed
// URL should be provided in CreateFunction or UpdateFunction request
// as a reference to the function source code.
//
// When uploading source code to the generated signed URL, please follow
// these restrictions:
//
//   Source file type should be a zip file.
//
//   Source file size should not exceed 100MB limit.
//
//   No credentials should be attached - the signed URLs provide access to the
//   target bucket using internal service identity; if credentials were
//   attached, the identity from the credentials would be used, but that
//   identity does not have permissions to upload files to the URL.
//
// When making a HTTP PUT request, these two headers need to be specified:
//
//   content-type: application/zip
//
//   x-goog-content-length-range: 0,104857600
//
// And this header SHOULD NOT be specified:
//
//   Authorization: Bearer YOUR_TOKEN
func (c *CloudFunctionsClient) GenerateUploadUrl(ctx context.Context, req *functionspb.GenerateUploadUrlRequest, opts ...gax.CallOption) (*functionspb.GenerateUploadUrlResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GenerateUploadUrl[0:len(c.CallOptions.GenerateUploadUrl):len(c.CallOptions.GenerateUploadUrl)], opts...)
	var resp *functionspb.GenerateUploadUrlResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.GenerateUploadUrl(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// GenerateDownloadUrl returns a signed URL for downloading deployed function source code.
// The URL is only valid for a limited period and should be used within
// minutes after generation.
// For more information about the signed URL usage see:
// https://cloud.google.com/storage/docs/access-control/signed-urls (at https://cloud.google.com/storage/docs/access-control/signed-urls)
func (c *CloudFunctionsClient) GenerateDownloadUrl(ctx context.Context, req *functionspb.GenerateDownloadUrlRequest, opts ...gax.CallOption) (*functionspb.GenerateDownloadUrlResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GenerateDownloadUrl[0:len(c.CallOptions.GenerateDownloadUrl):len(c.CallOptions.GenerateDownloadUrl)], opts...)
	var resp *functionspb.GenerateDownloadUrlResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.GenerateDownloadUrl(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// SetIamPolicy sets the IAM access control policy on the specified function.
// Replaces any existing policy.
func (c *CloudFunctionsClient) SetIamPolicy(ctx context.Context, req *iampb.SetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.SetIamPolicy[0:len(c.CallOptions.SetIamPolicy):len(c.CallOptions.SetIamPolicy)], opts...)
	var resp *iampb.Policy
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.SetIamPolicy(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// GetIamPolicy gets the IAM access control policy for a function.
// Returns an empty policy if the function exists and does not have a policy
// set.
func (c *CloudFunctionsClient) GetIamPolicy(ctx context.Context, req *iampb.GetIamPolicyRequest, opts ...gax.CallOption) (*iampb.Policy, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetIamPolicy[0:len(c.CallOptions.GetIamPolicy):len(c.CallOptions.GetIamPolicy)], opts...)
	var resp *iampb.Policy
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.GetIamPolicy(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// TestIamPermissions tests the specified permissions against the IAM access control policy
// for a function.
// If the function does not exist, this will return an empty set of
// permissions, not a NOT_FOUND error.
func (c *CloudFunctionsClient) TestIamPermissions(ctx context.Context, req *iampb.TestIamPermissionsRequest, opts ...gax.CallOption) (*iampb.TestIamPermissionsResponse, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", url.QueryEscape(req.GetResource())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.TestIamPermissions[0:len(c.CallOptions.TestIamPermissions):len(c.CallOptions.TestIamPermissions)], opts...)
	var resp *iampb.TestIamPermissionsResponse
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.cloudFunctionsClient.TestIamPermissions(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// CreateFunctionOperation manages a long-running operation from CreateFunction.
type CreateFunctionOperation struct {
	lro *longrunning.Operation
}

// CreateFunctionOperation returns a new CreateFunctionOperation from a given name.
// The name must be that of a previously created CreateFunctionOperation, possibly from a different process.
func (c *CloudFunctionsClient) CreateFunctionOperation(name string) *CreateFunctionOperation {
	return &CreateFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
	}
}

// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *CreateFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*functionspb.CloudFunction, error) {
	var resp functionspb.CloudFunction
	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
		return nil, err
	}
	return &resp, nil
}

// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *CreateFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*functionspb.CloudFunction, error) {
	var resp functionspb.CloudFunction
	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
		return nil, err
	}
	if !op.Done() {
		return nil, nil
	}
	return &resp, nil
}

// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *CreateFunctionOperation) Metadata() (*functionspb.OperationMetadataV1, error) {
	var meta functionspb.OperationMetadataV1
	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	return &meta, nil
}

// Done reports whether the long-running operation has completed.
func (op *CreateFunctionOperation) Done() bool {
	return op.lro.Done()
}

// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *CreateFunctionOperation) Name() string {
	return op.lro.Name()
}

// DeleteFunctionOperation manages a long-running operation from DeleteFunction.
type DeleteFunctionOperation struct {
	lro *longrunning.Operation
}

// DeleteFunctionOperation returns a new DeleteFunctionOperation from a given name.
// The name must be that of a previously created DeleteFunctionOperation, possibly from a different process.
func (c *CloudFunctionsClient) DeleteFunctionOperation(name string) *DeleteFunctionOperation {
	return &DeleteFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
	}
}

// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *DeleteFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
	return op.lro.WaitWithInterval(ctx, nil, time.Minute, opts...)
}

// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *DeleteFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) error {
	return op.lro.Poll(ctx, nil, opts...)
}

// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *DeleteFunctionOperation) Metadata() (*functionspb.OperationMetadataV1, error) {
	var meta functionspb.OperationMetadataV1
	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	return &meta, nil
}

// Done reports whether the long-running operation has completed.
func (op *DeleteFunctionOperation) Done() bool {
	return op.lro.Done()
}

// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *DeleteFunctionOperation) Name() string {
	return op.lro.Name()
}

// UpdateFunctionOperation manages a long-running operation from UpdateFunction.
type UpdateFunctionOperation struct {
	lro *longrunning.Operation
}

// UpdateFunctionOperation returns a new UpdateFunctionOperation from a given name.
// The name must be that of a previously created UpdateFunctionOperation, possibly from a different process.
func (c *CloudFunctionsClient) UpdateFunctionOperation(name string) *UpdateFunctionOperation {
	return &UpdateFunctionOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, &longrunningpb.Operation{Name: name}),
	}
}

// Wait blocks until the long-running operation is completed, returning the response and any errors encountered.
//
// See documentation of Poll for error-handling information.
func (op *UpdateFunctionOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*functionspb.CloudFunction, error) {
	var resp functionspb.CloudFunction
	if err := op.lro.WaitWithInterval(ctx, &resp, time.Minute, opts...); err != nil {
		return nil, err
	}
	return &resp, nil
}

// Poll fetches the latest state of the long-running operation.
//
// Poll also fetches the latest metadata, which can be retrieved by Metadata.
//
// If Poll fails, the error is returned and op is unmodified. If Poll succeeds and
// the operation has completed with failure, the error is returned and op.Done will return true.
// If Poll succeeds and the operation has completed successfully,
// op.Done will return true, and the response of the operation is returned.
// If Poll succeeds and the operation has not completed, the returned response and error are both nil.
func (op *UpdateFunctionOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*functionspb.CloudFunction, error) {
	var resp functionspb.CloudFunction
	if err := op.lro.Poll(ctx, &resp, opts...); err != nil {
		return nil, err
	}
	if !op.Done() {
		return nil, nil
	}
	return &resp, nil
}

// Metadata returns metadata associated with the long-running operation.
// Metadata itself does not contact the server, but Poll does.
// To get the latest metadata, call this method after a successful call to Poll.
// If the metadata is not available, the returned metadata and error are both nil.
func (op *UpdateFunctionOperation) Metadata() (*functionspb.OperationMetadataV1, error) {
	var meta functionspb.OperationMetadataV1
	if err := op.lro.Metadata(&meta); err == longrunning.ErrNoMetadata {
		return nil, nil
	} else if err != nil {
		return nil, err
	}
	return &meta, nil
}

// Done reports whether the long-running operation has completed.
func (op *UpdateFunctionOperation) Done() bool {
	return op.lro.Done()
}

// Name returns the name of the long-running operation.
// The name is assigned by the server and is unique within the service from which the operation is created.
func (op *UpdateFunctionOperation) Name() string {
	return op.lro.Name()
}

// CloudFunctionIterator manages a stream of *functionspb.CloudFunction.
type CloudFunctionIterator struct {
	items    []*functionspb.CloudFunction
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// Response is the raw response for the current page.
	// It must be cast to the RPC response type.
	// Calling Next() or InternalFetch() updates this value.
	Response interface{}

	// InternalFetch is for use by the Google Cloud Libraries only.
	// It is not part of the stable interface of this package.
	//
	// InternalFetch returns results from a single call to the underlying RPC.
	// The number of results is no greater than pageSize.
	// If there are no more results, nextPageToken is empty and err is nil.
	InternalFetch func(pageSize int, pageToken string) (results []*functionspb.CloudFunction, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *CloudFunctionIterator) PageInfo() *iterator.PageInfo {
	return it.pageInfo
}

// Next returns the next result. Its second return value is iterator.Done if there are no more
// results. Once Next returns Done, all subsequent calls will return Done.
func (it *CloudFunctionIterator) Next() (*functionspb.CloudFunction, error) {
	var item *functionspb.CloudFunction
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

func (it *CloudFunctionIterator) bufLen() int {
	return len(it.items)
}

func (it *CloudFunctionIterator) takeBuf() interface{} {
	b := it.items
	it.items = nil
	return b
}
