//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);
        }
        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();
            }
        }