// Copyright 2019 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 gapic-generator. DO NOT EDIT.

package vision

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

	"cloud.google.com/go/longrunning"
	lroauto "cloud.google.com/go/longrunning/autogen"
	"github.com/golang/protobuf/proto"
	gax "github.com/googleapis/gax-go/v2"
	"google.golang.org/api/iterator"
	"google.golang.org/api/option"
	"google.golang.org/api/transport"
	visionpb "google.golang.org/genproto/googleapis/cloud/vision/v1"
	longrunningpb "google.golang.org/genproto/googleapis/longrunning"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
)

// ProductSearchCallOptions contains the retry settings for each method of ProductSearchClient.
type ProductSearchCallOptions struct {
	CreateProductSet            []gax.CallOption
	ListProductSets             []gax.CallOption
	GetProductSet               []gax.CallOption
	UpdateProductSet            []gax.CallOption
	DeleteProductSet            []gax.CallOption
	CreateProduct               []gax.CallOption
	ListProducts                []gax.CallOption
	GetProduct                  []gax.CallOption
	UpdateProduct               []gax.CallOption
	DeleteProduct               []gax.CallOption
	CreateReferenceImage        []gax.CallOption
	DeleteReferenceImage        []gax.CallOption
	ListReferenceImages         []gax.CallOption
	GetReferenceImage           []gax.CallOption
	AddProductToProductSet      []gax.CallOption
	RemoveProductFromProductSet []gax.CallOption
	ListProductsInProductSet    []gax.CallOption
	ImportProductSets           []gax.CallOption
	PurgeProducts               []gax.CallOption
}

func defaultProductSearchClientOptions() []option.ClientOption {
	return []option.ClientOption{
		option.WithEndpoint("vision.googleapis.com:443"),
		option.WithScopes(DefaultAuthScopes()...),
		option.WithGRPCDialOption(grpc.WithDefaultCallOptions(
			grpc.MaxCallRecvMsgSize(math.MaxInt32))),
	}
}

func defaultProductSearchCallOptions() *ProductSearchCallOptions {
	retry := map[[2]string][]gax.CallOption{
		{"default", "idempotent"}: {
			gax.WithRetry(func() gax.Retryer {
				return gax.OnCodes([]codes.Code{
					codes.DeadlineExceeded,
					codes.Unavailable,
				}, gax.Backoff{
					Initial:    100 * time.Millisecond,
					Max:        60000 * time.Millisecond,
					Multiplier: 1.3,
				})
			}),
		},
	}
	return &ProductSearchCallOptions{
		CreateProductSet:            retry[[2]string{"default", "non_idempotent"}],
		ListProductSets:             retry[[2]string{"default", "idempotent"}],
		GetProductSet:               retry[[2]string{"default", "idempotent"}],
		UpdateProductSet:            retry[[2]string{"default", "idempotent"}],
		DeleteProductSet:            retry[[2]string{"default", "idempotent"}],
		CreateProduct:               retry[[2]string{"default", "non_idempotent"}],
		ListProducts:                retry[[2]string{"default", "idempotent"}],
		GetProduct:                  retry[[2]string{"default", "idempotent"}],
		UpdateProduct:               retry[[2]string{"default", "idempotent"}],
		DeleteProduct:               retry[[2]string{"default", "idempotent"}],
		CreateReferenceImage:        retry[[2]string{"default", "non_idempotent"}],
		DeleteReferenceImage:        retry[[2]string{"default", "idempotent"}],
		ListReferenceImages:         retry[[2]string{"default", "idempotent"}],
		GetReferenceImage:           retry[[2]string{"default", "idempotent"}],
		AddProductToProductSet:      retry[[2]string{"default", "idempotent"}],
		RemoveProductFromProductSet: retry[[2]string{"default", "idempotent"}],
		ListProductsInProductSet:    retry[[2]string{"default", "idempotent"}],
		ImportProductSets:           retry[[2]string{"default", "non_idempotent"}],
		PurgeProducts:               retry[[2]string{"default", "non_idempotent"}],
	}
}

// ProductSearchClient is a client for interacting with Cloud Vision API.
//
// Methods, except Close, may be called concurrently. However, fields must not be modified concurrently with method calls.
type ProductSearchClient struct {
	// The connection to the service.
	conn *grpc.ClientConn

	// The gRPC API client.
	productSearchClient visionpb.ProductSearchClient

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

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

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

// NewProductSearchClient creates a new product search client.
//
// Manages Products and ProductSets of reference images for use in product
// search. It uses the following resource model:
//
//   The API has a collection of [ProductSet][google.cloud.vision.v1.ProductSet]
//   resources, named projects/*/locations/*/productSets/*, which acts as a way
//   to put different products into groups to limit identification.
//
// In parallel,
//
//   The API has a collection of [Product][google.cloud.vision.v1.Product]
//   resources, named
//   projects/*/locations/*/products/*
//
//   Each [Product][google.cloud.vision.v1.Product] has a collection of
//   [ReferenceImage][google.cloud.vision.v1.ReferenceImage] resources, named
//   projects/*/locations/*/products/*/referenceImages/*
func NewProductSearchClient(ctx context.Context, opts ...option.ClientOption) (*ProductSearchClient, error) {
	conn, err := transport.DialGRPC(ctx, append(defaultProductSearchClientOptions(), opts...)...)
	if err != nil {
		return nil, err
	}
	c := &ProductSearchClient{
		conn:        conn,
		CallOptions: defaultProductSearchCallOptions(),

		productSearchClient: visionpb.NewProductSearchClient(conn),
	}
	c.setGoogleClientInfo()

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

// Connection returns the client's connection to the API service.
func (c *ProductSearchClient) Connection() *grpc.ClientConn {
	return c.conn
}

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

// CreateProductSet creates and returns a new ProductSet resource.
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if display_name is missing, or is longer than
//   4096 characters.
func (c *ProductSearchClient) CreateProductSet(ctx context.Context, req *visionpb.CreateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateProductSet[0:len(c.CallOptions.CreateProductSet):len(c.CallOptions.CreateProductSet)], opts...)
	var resp *visionpb.ProductSet
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.CreateProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListProductSets lists ProductSets in an unspecified order.
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if page_size is greater than 100, or less
//   than 1.
func (c *ProductSearchClient) ListProductSets(ctx context.Context, req *visionpb.ListProductSetsRequest, opts ...gax.CallOption) *ProductSetIterator {
	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.ListProductSets[0:len(c.CallOptions.ListProductSets):len(c.CallOptions.ListProductSets)], opts...)
	it := &ProductSetIterator{}
	req = proto.Clone(req).(*visionpb.ListProductSetsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ProductSet, string, error) {
		var resp *visionpb.ListProductSetsResponse
		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.productSearchClient.ListProductSets(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}
		return resp.ProductSets, resp.NextPageToken, 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.PageSize)
	it.pageInfo.Token = req.PageToken
	return it
}

// GetProductSet gets information associated with a ProductSet.
//
// Possible errors:
//
//   Returns NOT_FOUND if the ProductSet does not exist.
func (c *ProductSearchClient) GetProductSet(ctx context.Context, req *visionpb.GetProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetProductSet[0:len(c.CallOptions.GetProductSet):len(c.CallOptions.GetProductSet)], opts...)
	var resp *visionpb.ProductSet
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.GetProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateProductSet makes changes to a ProductSet resource.
// Only display_name can be updated currently.
//
// Possible errors:
//
//   Returns NOT_FOUND if the ProductSet does not exist.
//
//   Returns INVALID_ARGUMENT if display_name is present in update_mask but
//   missing from the request or longer than 4096 characters.
func (c *ProductSearchClient) UpdateProductSet(ctx context.Context, req *visionpb.UpdateProductSetRequest, opts ...gax.CallOption) (*visionpb.ProductSet, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product_set.name", url.QueryEscape(req.GetProductSet().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateProductSet[0:len(c.CallOptions.UpdateProductSet):len(c.CallOptions.UpdateProductSet)], opts...)
	var resp *visionpb.ProductSet
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.UpdateProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteProductSet permanently deletes a ProductSet. Products and ReferenceImages in the
// ProductSet are not deleted.
//
// The actual image files are not deleted from Google Cloud Storage.
func (c *ProductSearchClient) DeleteProductSet(ctx context.Context, req *visionpb.DeleteProductSetRequest, opts ...gax.CallOption) error {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteProductSet[0:len(c.CallOptions.DeleteProductSet):len(c.CallOptions.DeleteProductSet)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.productSearchClient.DeleteProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// CreateProduct creates and returns a new product resource.
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if display_name is missing or longer than 4096
//   characters.
//
//   Returns INVALID_ARGUMENT if description is longer than 4096 characters.
//
//   Returns INVALID_ARGUMENT if product_category is missing or invalid.
func (c *ProductSearchClient) CreateProduct(ctx context.Context, req *visionpb.CreateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateProduct[0:len(c.CallOptions.CreateProduct):len(c.CallOptions.CreateProduct)], opts...)
	var resp *visionpb.Product
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.CreateProduct(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// ListProducts lists products in an unspecified order.
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
func (c *ProductSearchClient) ListProducts(ctx context.Context, req *visionpb.ListProductsRequest, opts ...gax.CallOption) *ProductIterator {
	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.ListProducts[0:len(c.CallOptions.ListProducts):len(c.CallOptions.ListProducts)], opts...)
	it := &ProductIterator{}
	req = proto.Clone(req).(*visionpb.ListProductsRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) {
		var resp *visionpb.ListProductsResponse
		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.productSearchClient.ListProducts(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}
		return resp.Products, resp.NextPageToken, 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.PageSize)
	it.pageInfo.Token = req.PageToken
	return it
}

// GetProduct gets information associated with a Product.
//
// Possible errors:
//
//   Returns NOT_FOUND if the Product does not exist.
func (c *ProductSearchClient) GetProduct(ctx context.Context, req *visionpb.GetProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetProduct[0:len(c.CallOptions.GetProduct):len(c.CallOptions.GetProduct)], opts...)
	var resp *visionpb.Product
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.GetProduct(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// UpdateProduct makes changes to a Product resource.
// Only the display_name, description, and labels fields can be updated
// right now.
//
// If labels are updated, the change will not be reflected in queries until
// the next index time.
//
// Possible errors:
//
//   Returns NOT_FOUND if the Product does not exist.
//
//   Returns INVALID_ARGUMENT if display_name is present in update_mask but is
//   missing from the request or longer than 4096 characters.
//
//   Returns INVALID_ARGUMENT if description is present in update_mask but is
//   longer than 4096 characters.
//
//   Returns INVALID_ARGUMENT if product_category is present in update_mask.
func (c *ProductSearchClient) UpdateProduct(ctx context.Context, req *visionpb.UpdateProductRequest, opts ...gax.CallOption) (*visionpb.Product, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "product.name", url.QueryEscape(req.GetProduct().GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.UpdateProduct[0:len(c.CallOptions.UpdateProduct):len(c.CallOptions.UpdateProduct)], opts...)
	var resp *visionpb.Product
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.UpdateProduct(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteProduct permanently deletes a product and its reference images.
//
// Metadata of the product and all its images will be deleted right away, but
// search queries against ProductSets containing the product may still work
// until all related caches are refreshed.
func (c *ProductSearchClient) DeleteProduct(ctx context.Context, req *visionpb.DeleteProductRequest, opts ...gax.CallOption) error {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteProduct[0:len(c.CallOptions.DeleteProduct):len(c.CallOptions.DeleteProduct)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.productSearchClient.DeleteProduct(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// CreateReferenceImage creates and returns a new ReferenceImage resource.
//
// The bounding_poly field is optional. If bounding_poly is not specified,
// the system will try to detect regions of interest in the image that are
// compatible with the product_category on the parent product. If it is
// specified, detection is ALWAYS skipped. The system converts polygons into
// non-rotated rectangles.
//
// Note that the pipeline will resize the image if the image resolution is too
// large to process (above 50MP).
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if the image_uri is missing or longer than 4096
//   characters.
//
//   Returns INVALID_ARGUMENT if the product does not exist.
//
//   Returns INVALID_ARGUMENT if bounding_poly is not provided, and nothing
//   compatible with the parent product's product_category is detected.
//
//   Returns INVALID_ARGUMENT if bounding_poly contains more than 10 polygons.
func (c *ProductSearchClient) CreateReferenceImage(ctx context.Context, req *visionpb.CreateReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.CreateReferenceImage[0:len(c.CallOptions.CreateReferenceImage):len(c.CallOptions.CreateReferenceImage)], opts...)
	var resp *visionpb.ReferenceImage
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.CreateReferenceImage(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// DeleteReferenceImage permanently deletes a reference image.
//
// The image metadata will be deleted right away, but search queries
// against ProductSets containing the image may still work until all related
// caches are refreshed.
//
// The actual image files are not deleted from Google Cloud Storage.
func (c *ProductSearchClient) DeleteReferenceImage(ctx context.Context, req *visionpb.DeleteReferenceImageRequest, opts ...gax.CallOption) error {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.DeleteReferenceImage[0:len(c.CallOptions.DeleteReferenceImage):len(c.CallOptions.DeleteReferenceImage)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.productSearchClient.DeleteReferenceImage(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// ListReferenceImages lists reference images.
//
// Possible errors:
//
//   Returns NOT_FOUND if the parent product does not exist.
//
//   Returns INVALID_ARGUMENT if the page_size is greater than 100, or less
//   than 1.
func (c *ProductSearchClient) ListReferenceImages(ctx context.Context, req *visionpb.ListReferenceImagesRequest, opts ...gax.CallOption) *ReferenceImageIterator {
	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.ListReferenceImages[0:len(c.CallOptions.ListReferenceImages):len(c.CallOptions.ListReferenceImages)], opts...)
	it := &ReferenceImageIterator{}
	req = proto.Clone(req).(*visionpb.ListReferenceImagesRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.ReferenceImage, string, error) {
		var resp *visionpb.ListReferenceImagesResponse
		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.productSearchClient.ListReferenceImages(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}
		return resp.ReferenceImages, resp.NextPageToken, 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.PageSize)
	it.pageInfo.Token = req.PageToken
	return it
}

// GetReferenceImage gets information associated with a ReferenceImage.
//
// Possible errors:
//
//   Returns NOT_FOUND if the specified image does not exist.
func (c *ProductSearchClient) GetReferenceImage(ctx context.Context, req *visionpb.GetReferenceImageRequest, opts ...gax.CallOption) (*visionpb.ReferenceImage, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.GetReferenceImage[0:len(c.CallOptions.GetReferenceImage):len(c.CallOptions.GetReferenceImage)], opts...)
	var resp *visionpb.ReferenceImage
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.GetReferenceImage(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return resp, nil
}

// AddProductToProductSet adds a Product to the specified ProductSet. If the Product is already
// present, no change is made.
//
// One Product can be added to at most 100 ProductSets.
//
// Possible errors:
//
//   Returns NOT_FOUND if the Product or the ProductSet doesn't exist.
func (c *ProductSearchClient) AddProductToProductSet(ctx context.Context, req *visionpb.AddProductToProductSetRequest, opts ...gax.CallOption) error {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.AddProductToProductSet[0:len(c.CallOptions.AddProductToProductSet):len(c.CallOptions.AddProductToProductSet)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.productSearchClient.AddProductToProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// RemoveProductFromProductSet removes a Product from the specified ProductSet.
func (c *ProductSearchClient) RemoveProductFromProductSet(ctx context.Context, req *visionpb.RemoveProductFromProductSetRequest, opts ...gax.CallOption) error {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "name", url.QueryEscape(req.GetName())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.RemoveProductFromProductSet[0:len(c.CallOptions.RemoveProductFromProductSet):len(c.CallOptions.RemoveProductFromProductSet)], opts...)
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		_, err = c.productSearchClient.RemoveProductFromProductSet(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	return err
}

// ListProductsInProductSet lists the Products in a ProductSet, in an unspecified order. If the
// ProductSet does not exist, the products field of the response will be
// empty.
//
// Possible errors:
//
//   Returns INVALID_ARGUMENT if page_size is greater than 100 or less than 1.
func (c *ProductSearchClient) ListProductsInProductSet(ctx context.Context, req *visionpb.ListProductsInProductSetRequest, opts ...gax.CallOption) *ProductIterator {
	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.ListProductsInProductSet[0:len(c.CallOptions.ListProductsInProductSet):len(c.CallOptions.ListProductsInProductSet)], opts...)
	it := &ProductIterator{}
	req = proto.Clone(req).(*visionpb.ListProductsInProductSetRequest)
	it.InternalFetch = func(pageSize int, pageToken string) ([]*visionpb.Product, string, error) {
		var resp *visionpb.ListProductsInProductSetResponse
		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.productSearchClient.ListProductsInProductSet(ctx, req, settings.GRPC...)
			return err
		}, opts...)
		if err != nil {
			return nil, "", err
		}
		return resp.Products, resp.NextPageToken, 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.PageSize)
	it.pageInfo.Token = req.PageToken
	return it
}

// ImportProductSets asynchronous API that imports a list of reference images to specified
// product sets based on a list of image information.
//
// The [google.longrunning.Operation][google.longrunning.Operation] API can be
// used to keep track of the progress and results of the request.
// Operation.metadata contains BatchOperationMetadata. (progress)
// Operation.response contains ImportProductSetsResponse. (results)
//
// The input source of this method is a csv file on Google Cloud Storage.
// For the format of the csv file please see
// [ImportProductSetsGcsSource.csv_file_uri][google.cloud.vision.v1.ImportProductSetsGcsSource.csv_file_uri].
func (c *ProductSearchClient) ImportProductSets(ctx context.Context, req *visionpb.ImportProductSetsRequest, opts ...gax.CallOption) (*ImportProductSetsOperation, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.ImportProductSets[0:len(c.CallOptions.ImportProductSets):len(c.CallOptions.ImportProductSets)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.ImportProductSets(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &ImportProductSetsOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, resp),
	}, nil
}

// PurgeProducts asynchronous API to delete all Products in a ProductSet or all Products
// that are in no ProductSet.
//
// If a Product is a member of the specified ProductSet in addition to other
// ProductSets, the Product will still be deleted.
//
// It is recommended to not delete the specified ProductSet until after this
// operation has completed. It is also recommended to not add any of the
// Products involved in the batch delete to a new ProductSet while this
// operation is running because those Products may still end up deleted.
//
// It's not possible to undo the PurgeProducts operation. Therefore, it is
// recommended to keep the csv files used in ImportProductSets (if that was
// how you originally built the Product Set) before starting PurgeProducts, in
// case you need to re-import the data after deletion.
//
// If the plan is to purge all of the Products from a ProductSet and then
// re-use the empty ProductSet to re-import new Products into the empty
// ProductSet, you must wait until the PurgeProducts operation has finished
// for that ProductSet.
//
// The [google.longrunning.Operation][google.longrunning.Operation] API can be
// used to keep track of the progress and results of the request.
// Operation.metadata contains BatchOperationMetadata. (progress)
func (c *ProductSearchClient) PurgeProducts(ctx context.Context, req *visionpb.PurgeProductsRequest, opts ...gax.CallOption) (*PurgeProductsOperation, error) {
	md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "parent", url.QueryEscape(req.GetParent())))
	ctx = insertMetadata(ctx, c.xGoogMetadata, md)
	opts = append(c.CallOptions.PurgeProducts[0:len(c.CallOptions.PurgeProducts):len(c.CallOptions.PurgeProducts)], opts...)
	var resp *longrunningpb.Operation
	err := gax.Invoke(ctx, func(ctx context.Context, settings gax.CallSettings) error {
		var err error
		resp, err = c.productSearchClient.PurgeProducts(ctx, req, settings.GRPC...)
		return err
	}, opts...)
	if err != nil {
		return nil, err
	}
	return &PurgeProductsOperation{
		lro: longrunning.InternalNewOperation(c.LROClient, resp),
	}, nil
}

// ProductIterator manages a stream of *visionpb.Product.
type ProductIterator struct {
	items    []*visionpb.Product
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// 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 []*visionpb.Product, nextPageToken string, err error)
}

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

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

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

// ProductSetIterator manages a stream of *visionpb.ProductSet.
type ProductSetIterator struct {
	items    []*visionpb.ProductSet
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// 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 []*visionpb.ProductSet, nextPageToken string, err error)
}

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

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

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

// ReferenceImageIterator manages a stream of *visionpb.ReferenceImage.
type ReferenceImageIterator struct {
	items    []*visionpb.ReferenceImage
	pageInfo *iterator.PageInfo
	nextFunc func() error

	// 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 []*visionpb.ReferenceImage, nextPageToken string, err error)
}

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

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

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

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

// ImportProductSetsOperation returns a new ImportProductSetsOperation from a given name.
// The name must be that of a previously created ImportProductSetsOperation, possibly from a different process.
func (c *ProductSearchClient) ImportProductSetsOperation(name string) *ImportProductSetsOperation {
	return &ImportProductSetsOperation{
		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 *ImportProductSetsOperation) Wait(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) {
	var resp visionpb.ImportProductSetsResponse
	if err := op.lro.WaitWithInterval(ctx, &resp, 45000*time.Millisecond, 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 *ImportProductSetsOperation) Poll(ctx context.Context, opts ...gax.CallOption) (*visionpb.ImportProductSetsResponse, error) {
	var resp visionpb.ImportProductSetsResponse
	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 *ImportProductSetsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) {
	var meta visionpb.BatchOperationMetadata
	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 *ImportProductSetsOperation) 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 *ImportProductSetsOperation) Name() string {
	return op.lro.Name()
}

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

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

// Wait blocks until the long-running operation is completed, returning any error encountered.
//
// See documentation of Poll for error-handling information.
func (op *PurgeProductsOperation) Wait(ctx context.Context, opts ...gax.CallOption) error {
	return op.lro.WaitWithInterval(ctx, nil, 45000*time.Millisecond, 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.
func (op *PurgeProductsOperation) 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 *PurgeProductsOperation) Metadata() (*visionpb.BatchOperationMetadata, error) {
	var meta visionpb.BatchOperationMetadata
	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 *PurgeProductsOperation) 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 *PurgeProductsOperation) Name() string {
	return op.lro.Name()
}
