//public async Task<Target> CreateTarget(string displayName, string description, IReadOnlyDictionary<string, string> labels, byte[] referenceImageBinaries)
        //{
        //    GoogleCredential cred = this.CreateCredentials();
        //    var channel = new Channel(ProductSearchClient.DefaultEndpoint.Host, ProductSearchClient.DefaultEndpoint.Port, cred.ToChannelCredentials());

        //    try
        //    {
        //        var client = ProductSearchClient.Create(channel);
        //        var storage = await StorageClient.CreateAsync(cred);

        //        string productId = Guid.NewGuid().ToString();
        //        var createProductOptions = new CreateProductOptions
        //        {
        //            ProjectID = this.options.Value.ProjectId,
        //            ComputeRegion = this.options.Value.LocationId,
        //            ProductID = productId,
        //            ProductCategory = "apparel",
        //            DisplayName = displayName,
        //            Description = description,
        //            ProductLabels = labels,
        //        };
        //        Product product = await this.CreateProduct(client, createProductOptions);

        //        var addProductOptions = new AddProductToProductSetOptions
        //        {
        //            ProjectID = this.options.Value.ProjectId,
        //            ComputeRegion = this.options.Value.LocationId,
        //            ProductID = product.ProductName.ProductId,
        //            ProductSetId = this.options.Value.ProductSetId,
        //        };
        //        await this.AddProductToProductSet(client, addProductOptions);

        //        string referenceImageId = Guid.NewGuid().ToString();
        //        await this.UploadFile(storage, this.options.Value.StorageBucketName, referenceImageId, referenceImageBinaries);

        //        var createReferenceImageOptions = new CreateReferenceImageOptions
        //        {
        //            ProjectID = this.options.Value.ProjectId,
        //            ComputeRegion = this.options.Value.LocationId,
        //            ProductID = product.ProductName.ProductId,
        //            ReferenceImageID = referenceImageId,
        //            ReferenceImageURI = $"gs://{this.options.Value.StorageBucketName}/{referenceImageId}",
        //        };
        //        Google.Cloud.Vision.V1.ReferenceImage referenceImage = await this.CreateReferenceImage(client, createReferenceImageOptions);

        //        Target target = this.mapper.Map<Target>(product);
        //        target.ReferenceImages = new ReferenceImage[] { this.mapper.Map<ReferenceImage>(referenceImage) };

        //        return target;
        //    }
        //    finally
        //    {
        //        await channel.ShutdownAsync();
        //    }
        //}

        //public async Task DeleteTarget(string targetSetId, string targetId)
        //{
        //    GoogleCredential cred = this.CreateCredentials();
        //    var channel = new Channel(ProductSearchClient.DefaultEndpoint.Host, ProductSearchClient.DefaultEndpoint.Port, cred.ToChannelCredentials());

        //    try
        //    {
        //        var client = ProductSearchClient.Create(channel);
        //        var storage = await StorageClient.CreateAsync(cred);

        //        IEnumerable<Google.Cloud.Vision.V1.ReferenceImage> referenceImages = await this.GetReferenceImages(client, targetId, 100);
        //        await Task.WhenAll(referenceImages.Select(async r =>
        //        {
        //            await this.DeleteReferenceImage(client, targetId, r.ReferenceImageName.ReferenceImageId);
        //            await this.DeleteFile(storage, this.options.Value.StorageBucketName, r.ReferenceImageName.ReferenceImageId);
        //        }));

        //        await this.RemoveProductFromProductSet(client, targetSetId, targetId);
        //        await this.DeleteProduct(client, targetId);

        //    }
        //    finally
        //    {
        //        await channel.ShutdownAsync();
        //    }
        //}

        //public async Task<TargetSearchResults> QuerySimilarTargets(byte[] image)
        //{
        //    GoogleCredential cred = this.CreateCredentials();
        //    var channel = new Channel(ProductSearchClient.DefaultEndpoint.Host, ProductSearchClient.DefaultEndpoint.Port, cred.ToChannelCredentials());

        //    try
        //    {
        //        var imageAnnotatorClient = ImageAnnotatorClient.Create(channel);

        //        var options = new GetSimilarProductsOptions
        //        {
        //            ProjectID = this.options.Value.ProjectId,
        //            ComputeRegion = this.options.Value.LocationId,
        //            ProductSetId = this.options.Value.ProductSetId,
        //            ProductCategory = "apparel",
        //            Filter = string.Empty,
        //            ImageBinaries = image,
        //        };

        //        return await this.GetSimilarProductsFile(imageAnnotatorClient, options);
        //    }
        //    catch (AnnotateImageException e)
        //    {
        //        this.logger.LogError(e, "The google cloud image recognition service threw an error.");
        //        return new TargetSearchResults
        //        {
        //            Results = new TargetSearchResultEntry[0],
        //        };
        //    }
        //    finally
        //    {
        //        await channel.ShutdownAsync();
        //    }
        //}

        //private async Task<ProductSet> CreateProductSet(ProductSearchClient client, CreateProductSetsOptions opts)
        //{
        //    // Create a product set with the product set specification in the region.
        //    var request = new CreateProductSetRequest
        //    {
        //        // A resource that represents Google Cloud Platform location
        //        ParentAsLocationName = new LocationName(opts.ProjectID, opts.ComputeRegion),
        //        ProductSetId = opts.ProductSetId,
        //        ProductSet = new ProductSet
        //        {
        //            DisplayName = opts.ProductSetDisplayName
        //        }
        //    };

        //    // The response is the product set with the `name` populated
        //    var response = await client.CreateProductSetAsync(request);

        //    return response;
        //}


        ////private async Task<ProductSet> GetProductSets(ProductSearchClient client, int pageSize)
        ////{
        ////    var request = new ListProductSetsRequest
        ////    {
        ////        ParentAsLocationName = new LocationName(this.options.Value.ProjectId, this.options.Value.LocationId),
        ////        PageSize = pageSize,
        ////    };

        ////    return await client.ListProductSets(request);
        ////}

        //private async Task<Product> CreateProduct(ProductSearchClient client, CreateProductOptions opts)
        //{
        //    var request = new CreateProductRequest
        //    {
        //        // A resource that represents Google Cloud Platform location.
        //        ParentAsLocationName = new LocationName(opts.ProjectID, opts.ComputeRegion),
        //        // Set product category and product display name
        //        Product = new Product
        //        {
        //            DisplayName = opts.DisplayName,
        //            ProductCategory = opts.ProductCategory,
        //            Description = opts.Description ?? string.Empty,
        //        },
        //        ProductId = opts.ProductID
        //    };

        //    foreach (var label in opts.ProductLabels)
        //    {
        //        request.Product.ProductLabels.Add(new KeyValue { Key = label.Key, Value = label.Value });
        //    }

        //    // The response is the product with the `name` field populated.
        //    var product = await client.CreateProductAsync(request);

        //    return product;
        //}

        private async Task <Product> GetProduct(ProductSearchClient client, string productId)
        {
            var request = new GetProductRequest
            {
                ProductName = new ProductName(this.options.Value.ProjectId, this.options.Value.LocationId, productId),
            };

            return(await client.GetProductAsync(request));
        }