// 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", getVersionClient(), "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
}
