// Copyright 2021 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.WithDisableServiceConfig()),
		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) {
		var resp *networkmanagementpb.ListConnectivityTestsResponse
		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.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
}
