// Copyright 2022 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 networkmanagement

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

	"cloud.google.com/go/longrunning"
	lroauto "cloud.google.com/go/longrunning/autogen"
	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"
	networkmanagementpb "google.golang.org/genproto/googleapis/cloud/networkmanagement/v1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
	"google.golang.org/protobuf/proto"
)

var newReachabilityClientHook clientHook

// ReachabilityCallOptions contains the retry settings for each method of ReachabilityClient.
type ReachabilityCallOptions struct {
	ListConnectivityTests  []gax.CallOption
	GetConnectivityTest    []gax.CallOption
	CreateConnectivityTest []gax.CallOption
	UpdateConnectivityTest []gax.CallOption
	RerunConnectivityTest  []gax.CallOption
	DeleteConnectivityTest []gax.CallOption
}

func defaultReachabilityGRPCClientOptions() []option.ClientOption {
	return []option.ClientOption{
		internaloption.WithDefaultEndpoint("networkmanagement.googleapis.com:443"),
		internaloption.WithDefaultMTLSEndpoint("networkmanagement.mtls.googleapis.com:443"),
		internaloption.WithDefaultAudience("https://networkmanagement.googleapis.com/"),
		internaloption.WithDefaultScopes(DefaultAuthScopes()...),
		internaloption.EnableJwtWithScope(),
		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
	}
}

func defaultReachabilityCallOptions() *ReachabilityCallOptions {
	return &ReachabilityCallOptions{
		ListConnectivityTests:  []gax.CallOption{},
		GetConnectivityTest:    []gax.CallOption{},
		CreateConnectivityTest: []gax.CallOption{},
		UpdateConnectivityTest: []gax.CallOption{},
		RerunConnectivityTest:  []gax.CallOption{},
		DeleteConnectivityTest: []gax.CallOption{},
	}
}

// internalReachabilityClient is an interface that defines the methods availaible from Network Management API.
type internalReachabilityClient interface {
	Close() error
	setGoogleClientInfo(...string)
	Connection() *grpc.ClientConn
	ListConnectivityTests(context.Context, *networkmanagementpb.ListConnectivityTestsRequest, ...gax.CallOption) *ConnectivityTestIterator
	GetConnectivityTest(context.Context, *networkmanagementpb.GetConnectivityTestRequest, ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error)
	CreateConnectivityTest(context.Context, *networkmanagementpb.CreateConnectivityTestRequest, ...gax.CallOption) (*CreateConnectivityTestOperation, error)
	CreateConnectivityTestOperation(name string) *CreateConnectivityTestOperation
	UpdateConnectivityTest(context.Context, *networkmanagementpb.UpdateConnectivityTestRequest, ...gax.CallOption) (*UpdateConnectivityTestOperation, error)
	UpdateConnectivityTestOperation(name string) *UpdateConnectivityTestOperation
	RerunConnectivityTest(context.Context, *networkmanagementpb.RerunConnectivityTestRequest, ...gax.CallOption) (*RerunConnectivityTestOperation, error)
	RerunConnectivityTestOperation(name string) *RerunConnectivityTestOperation
	DeleteConnectivityTest(context.Context, *networkmanagementpb.DeleteConnectivityTestRequest, ...gax.CallOption) (*DeleteConnectivityTestOperation, error)
	DeleteConnectivityTestOperation(name string) *DeleteConnectivityTestOperation
}

// ReachabilityClient is a client for interacting with Network Management API.
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
//
// The Reachability service in the Google Cloud Network Management API provides
// services that analyze the reachability within a single Google Virtual Private
// Cloud (VPC) network, between peered VPC networks, between VPC and on-premises
// networks, or between VPC networks and internet hosts. A reachability analysis
// is based on Google Cloud network configurations.
//
// You can use the analysis results to verify these configurations and
// to troubleshoot connectivity issues.
type ReachabilityClient struct {
	// The internal transport-dependent client.
	internalClient internalReachabilityClient

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

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

// Wrapper methods routed to the internal client.

// Close closes the connection to the API service. The user should invoke this when
// the client is no longer required.
func (c *ReachabilityClient) Close() error {
	return c.internalClient.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 *ReachabilityClient) setGoogleClientInfo(keyval ...string) {
	c.internalClient.setGoogleClientInfo(keyval...)
}

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

// ListConnectivityTests lists all Connectivity Tests owned by a project.
func (c *ReachabilityClient) ListConnectivityTests(ctx context.Context, req *networkmanagementpb.ListConnectivityTestsRequest, opts ...gax.CallOption) *ConnectivityTestIterator {
	return c.internalClient.ListConnectivityTests(ctx, req, opts...)
}

// GetConnectivityTest gets the details of a specific Connectivity Test.
func (c *ReachabilityClient) GetConnectivityTest(ctx context.Context, req *networkmanagementpb.GetConnectivityTestRequest, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	return c.internalClient.GetConnectivityTest(ctx, req, opts...)
}

// CreateConnectivityTest creates a new Connectivity Test.
// After you create a test, the reachability analysis is performed as part
// of the long running operation, which completes when the analysis completes.
//
// If the endpoint specifications in ConnectivityTest are invalid
// (for example, containing non-existent resources in the network, or you
// don’t have read permissions to the network configurations of listed
// projects), then the reachability result returns a value of UNKNOWN.
//
// If the endpoint specifications in ConnectivityTest are
// incomplete, the reachability result returns a value of
// AMBIGUOUS. For more information,
// see the Connectivity Test documentation.
func (c *ReachabilityClient) CreateConnectivityTest(ctx context.Context, req *networkmanagementpb.CreateConnectivityTestRequest, opts ...gax.CallOption) (*CreateConnectivityTestOperation, error) {
	return c.internalClient.CreateConnectivityTest(ctx, req, opts...)
}

// CreateConnectivityTestOperation returns a new CreateConnectivityTestOperation from a given name.
// The name must be that of a previously created CreateConnectivityTestOperation, possibly from a different process.
func (c *ReachabilityClient) CreateConnectivityTestOperation(name string) *CreateConnectivityTestOperation {
	return c.internalClient.CreateConnectivityTestOperation(name)
}

// UpdateConnectivityTest updates the configuration of an existing ConnectivityTest.
// After you update a test, the reachability analysis is performed as part
// of the long running operation, which completes when the analysis completes.
// The Reachability state in the test resource is updated with the new result.
//
// If the endpoint specifications in ConnectivityTest are invalid
// (for example, they contain non-existent resources in the network, or the
// user does not have read permissions to the network configurations of
// listed projects), then the reachability result returns a value of
// UNKNOWN.
//
// If the endpoint specifications in ConnectivityTest are incomplete, the
// reachability result returns a value of AMBIGUOUS. See the documentation
// in ConnectivityTest for for more details.
func (c *ReachabilityClient) UpdateConnectivityTest(ctx context.Context, req *networkmanagementpb.UpdateConnectivityTestRequest, opts ...gax.CallOption) (*UpdateConnectivityTestOperation, error) {
	return c.internalClient.UpdateConnectivityTest(ctx, req, opts...)
}

// UpdateConnectivityTestOperation returns a new UpdateConnectivityTestOperation from a given name.
// The name must be that of a previously created UpdateConnectivityTestOperation, possibly from a different process.
func (c *ReachabilityClient) UpdateConnectivityTestOperation(name string) *UpdateConnectivityTestOperation {
	return c.internalClient.UpdateConnectivityTestOperation(name)
}

// RerunConnectivityTest rerun an existing ConnectivityTest.
// After the user triggers the rerun, the reachability analysis is performed
// as part of the long running operation, which completes when the analysis
// completes.
//
// Even though the test configuration remains the same, the reachability
// result may change due to underlying network configuration changes.
//
// If the endpoint specifications in ConnectivityTest become invalid (for
// example, specified resources are deleted in the network, or you lost
// read permissions to the network configurations of listed projects), then
// the reachability result returns a value of UNKNOWN.
func (c *ReachabilityClient) RerunConnectivityTest(ctx context.Context, req *networkmanagementpb.RerunConnectivityTestRequest, opts ...gax.CallOption) (*RerunConnectivityTestOperation, error) {
	return c.internalClient.RerunConnectivityTest(ctx, req, opts...)
}

// RerunConnectivityTestOperation returns a new RerunConnectivityTestOperation from a given name.
// The name must be that of a previously created RerunConnectivityTestOperation, possibly from a different process.
func (c *ReachabilityClient) RerunConnectivityTestOperation(name string) *RerunConnectivityTestOperation {
	return c.internalClient.RerunConnectivityTestOperation(name)
}

// DeleteConnectivityTest deletes a specific ConnectivityTest.
func (c *ReachabilityClient) DeleteConnectivityTest(ctx context.Context, req *networkmanagementpb.DeleteConnectivityTestRequest, opts ...gax.CallOption) (*DeleteConnectivityTestOperation, error) {
	return c.internalClient.DeleteConnectivityTest(ctx, req, opts...)
}

// DeleteConnectivityTestOperation returns a new DeleteConnectivityTestOperation from a given name.
// The name must be that of a previously created DeleteConnectivityTestOperation, possibly from a different process.
func (c *ReachabilityClient) DeleteConnectivityTestOperation(name string) *DeleteConnectivityTestOperation {
	return c.internalClient.DeleteConnectivityTestOperation(name)
}

// reachabilityGRPCClient is a client for interacting with Network Management API over gRPC transport.
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type reachabilityGRPCClient 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

	// Points back to the CallOptions field of the containing ReachabilityClient
	CallOptions **ReachabilityCallOptions

	// The gRPC API client.
	reachabilityClient networkmanagementpb.ReachabilityServiceClient

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

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

// NewReachabilityClient creates a new reachability service client based on gRPC.
// The returned client must be Closed when it is done being used to clean up its underlying connections.
//
// The Reachability service in the Google Cloud Network Management API provides
// services that analyze the reachability within a single Google Virtual Private
// Cloud (VPC) network, between peered VPC networks, between VPC and on-premises
// networks, or between VPC networks and internet hosts. A reachability analysis
// is based on Google Cloud network configurations.
//
// You can use the analysis results to verify these configurations and
// to troubleshoot connectivity issues.
func NewReachabilityClient(ctx context.Context, opts ...option.ClientOption) (*ReachabilityClient, error) {
	clientOpts := defaultReachabilityGRPCClientOptions()
	if newReachabilityClientHook != nil {
		hookOpts, err := newReachabilityClientHook(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
	}
	client := ReachabilityClient{CallOptions: defaultReachabilityCallOptions()}

	c := &reachabilityGRPCClient{
		connPool:           connPool,
		disableDeadlines:   disableDeadlines,
		reachabilityClient: networkmanagementpb.NewReachabilityServiceClient(connPool),
		CallOptions:        &client.CallOptions,
	}
	c.setGoogleClientInfo()

	client.internalClient = c

	client.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
	}
	c.LROClient = &client.LROClient
	return &client, nil
}

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

// 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 *reachabilityGRPCClient) 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...))
}

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

func (c *reachabilityGRPCClient) ListConnectivityTests(ctx context.Context, req *networkmanagementpb.ListConnectivityTestsRequest, opts ...gax.CallOption) *ConnectivityTestIterator {
	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).ListConnectivityTests[0:len((*c.CallOptions).ListConnectivityTests):len((*c.CallOptions).ListConnectivityTests)], opts...)
	it := &ConnectivityTestIterator{}
	req = proto.Clone(req).(*networkmanagementpb.ListConnectivityTestsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*networkmanagementpb.ConnectivityTest, string, error) {
		resp := &networkmanagementpb.ListConnectivityTestsResponse{}
		if pageToken != "" {
			req.PageToken = pageToken
		}
		if pageSize > math.MaxInt32 {
			req.PageSize = math.MaxInt32
		} else if pageSize != 0 {
			req.PageSize = int32(pageSize)
		}
		err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
			var err error
			resp, err = c.reachabilityClient.ListConnectivityTests(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}

		it.Response = resp
		return resp.GetResources(), 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
}

func (c *reachabilityGRPCClient) GetConnectivityTest(ctx context.Context, req *networkmanagementpb.GetConnectivityTestRequest, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	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).GetConnectivityTest[0:len((*c.CallOptions).GetConnectivityTest):len((*c.CallOptions).GetConnectivityTest)], opts...)
	var resp *networkmanagementpb.ConnectivityTest
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.reachabilityClient.GetConnectivityTest(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

func (c *reachabilityGRPCClient) CreateConnectivityTest(ctx context.Context, req *networkmanagementpb.CreateConnectivityTestRequest, opts ...gax.CallOption) (*CreateConnectivityTestOperation, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	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).CreateConnectivityTest[0:len((*c.CallOptions).CreateConnectivityTest):len((*c.CallOptions).CreateConnectivityTest)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.reachabilityClient.CreateConnectivityTest(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &CreateConnectivityTestOperation{
		lro: longrunning.InternalNewOperation(*c.LROClient, resp),
	}, nil
}

func (c *reachabilityGRPCClient) UpdateConnectivityTest(ctx context.Context, req *networkmanagementpb.UpdateConnectivityTestRequest, opts ...gax.CallOption) (*UpdateConnectivityTestOperation, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource.name", url.QueryEscape(req.GetResource().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append((*c.CallOptions).UpdateConnectivityTest[0:len((*c.CallOptions).UpdateConnectivityTest):len((*c.CallOptions).UpdateConnectivityTest)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.reachabilityClient.UpdateConnectivityTest(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &UpdateConnectivityTestOperation{
		lro: longrunning.InternalNewOperation(*c.LROClient, resp),
	}, nil
}

func (c *reachabilityGRPCClient) RerunConnectivityTest(ctx context.Context, req *networkmanagementpb.RerunConnectivityTestRequest, opts ...gax.CallOption) (*RerunConnectivityTestOperation, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	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).RerunConnectivityTest[0:len((*c.CallOptions).RerunConnectivityTest):len((*c.CallOptions).RerunConnectivityTest)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.reachabilityClient.RerunConnectivityTest(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &RerunConnectivityTestOperation{
		lro: longrunning.InternalNewOperation(*c.LROClient, resp),
	}, nil
}

func (c *reachabilityGRPCClient) DeleteConnectivityTest(ctx context.Context, req *networkmanagementpb.DeleteConnectivityTestRequest, opts ...gax.CallOption) (*DeleteConnectivityTestOperation, error) {
	if _, ok := ctx.Deadline(); !ok && !c.disableDeadlines {
		cctx, cancel := context.WithTimeout(ctx, 60000*time.Millisecond)
		defer cancel()
		ctx = cctx
	}
	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).DeleteConnectivityTest[0:len((*c.CallOptions).DeleteConnectivityTest):len((*c.CallOptions).DeleteConnectivityTest)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.reachabilityClient.DeleteConnectivityTest(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &DeleteConnectivityTestOperation{
		lro: longrunning.InternalNewOperation(*c.LROClient, resp),
	}, nil
}

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

// CreateConnectivityTestOperation returns a new CreateConnectivityTestOperation from a given name.
// The name must be that of a previously created CreateConnectivityTestOperation, possibly from a different process.
func (c *reachabilityGRPCClient) CreateConnectivityTestOperation(name string) *CreateConnectivityTestOperation {
	return &CreateConnectivityTestOperation{
		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 *CreateConnectivityTestOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *CreateConnectivityTestOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *CreateConnectivityTestOperation) Metadata() (*networkmanagementpb.OperationMetadata, error) {
	var meta networkmanagementpb.OperationMetadata
	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 *CreateConnectivityTestOperation) 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 *CreateConnectivityTestOperation) Name() string {
	return op.lro.Name()
}

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

// DeleteConnectivityTestOperation returns a new DeleteConnectivityTestOperation from a given name.
// The name must be that of a previously created DeleteConnectivityTestOperation, possibly from a different process.
func (c *reachabilityGRPCClient) DeleteConnectivityTestOperation(name string) *DeleteConnectivityTestOperation {
	return &DeleteConnectivityTestOperation{
		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 *DeleteConnectivityTestOperation) 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 *DeleteConnectivityTestOperation) 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 *DeleteConnectivityTestOperation) Metadata() (*networkmanagementpb.OperationMetadata, error) {
	var meta networkmanagementpb.OperationMetadata
	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 *DeleteConnectivityTestOperation) 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 *DeleteConnectivityTestOperation) Name() string {
	return op.lro.Name()
}

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

// RerunConnectivityTestOperation returns a new RerunConnectivityTestOperation from a given name.
// The name must be that of a previously created RerunConnectivityTestOperation, possibly from a different process.
func (c *reachabilityGRPCClient) RerunConnectivityTestOperation(name string) *RerunConnectivityTestOperation {
	return &RerunConnectivityTestOperation{
		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 *RerunConnectivityTestOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *RerunConnectivityTestOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *RerunConnectivityTestOperation) Metadata() (*networkmanagementpb.OperationMetadata, error) {
	var meta networkmanagementpb.OperationMetadata
	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 *RerunConnectivityTestOperation) 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 *RerunConnectivityTestOperation) Name() string {
	return op.lro.Name()
}

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

// UpdateConnectivityTestOperation returns a new UpdateConnectivityTestOperation from a given name.
// The name must be that of a previously created UpdateConnectivityTestOperation, possibly from a different process.
func (c *reachabilityGRPCClient) UpdateConnectivityTestOperation(name string) *UpdateConnectivityTestOperation {
	return &UpdateConnectivityTestOperation{
		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 *UpdateConnectivityTestOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *UpdateConnectivityTestOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*networkmanagementpb.ConnectivityTest, error) {
	var resp networkmanagementpb.ConnectivityTest
	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 *UpdateConnectivityTestOperation) Metadata() (*networkmanagementpb.OperationMetadata, error) {
	var meta networkmanagementpb.OperationMetadata
	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 *UpdateConnectivityTestOperation) 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 *UpdateConnectivityTestOperation) Name() string {
	return op.lro.Name()
}

// ConnectivityTestIterator manages a stream of *networkmanagementpb.ConnectivityTest.
type ConnectivityTestIterator struct {
	items    []*networkmanagementpb.ConnectivityTest
	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 []*networkmanagementpb.ConnectivityTest, nextPageToken string, err error)
}

// PageInfo supports pagination. See the google.golang.org/api/iterator package for details.
func (it *ConnectivityTestIterator) 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 *ConnectivityTestIterator) Next() (*networkmanagementpb.ConnectivityTest, error) {
	var item *networkmanagementpb.ConnectivityTest
	if err := it.nextFunc(); err != nil {
		return item, err
	}
	item = it.items[0]
	it.items = it.items[1:]
	return item, nil
}

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

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