// Package computervision implements the Azure ARM Computervision service API version 1.0.
//
// The Computer Vision API provides state-of-the-art algorithms to process images and return information. For example,
// it can be used to determine if an image contains mature content, or it can be used to find all the faces in an
// image.  It also has other features like estimating dominant and accent colors, categorizing the content of images,
// and describing an image with complete English sentences.  Additionally, it can also intelligently generate images
// thumbnails for displaying large images effectively.
package computervision

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// 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
// http://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 Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"github.com/Azure/go-autorest/autorest/validation"
	"io"
	"net/http"
)

// BaseClient is the base client for Computervision.
type BaseClient struct {
	autorest.Client
	AzureRegion AzureRegions
}

// New creates an instance of the BaseClient client.
func New(azureRegion AzureRegions) BaseClient {
	return NewWithoutDefaults(azureRegion)
}

// NewWithoutDefaults creates an instance of the BaseClient client.
func NewWithoutDefaults(azureRegion AzureRegions) BaseClient {
	return BaseClient{
		Client:      autorest.NewClientWithUserAgent(UserAgent()),
		AzureRegion: azureRegion,
	}
}

// AnalyzeImage this operation extracts a rich set of visual features based on the image content. Two input methods are
// supported -- (1) Uploading an image or (2) specifying an image URL.  Within your request, there is an optional
// parameter to allow you to choose which features to return.  By default, image categories are returned in the
// response.
//
// imageURL is a JSON document with a URL pointing to the image that is to be analyzed. visualFeatures is a string
// indicating what visual feature types to return. Multiple values should be comma-separated. Valid visual feature
// types include:Categories - categorizes image content according to a taxonomy defined in documentation. Tags - tags
// the image with a detailed list of words related to the image content. Description - describes the image content with
// a complete English sentence. Faces - detects if faces are present. If present, generate coordinates, gender and age.
// ImageType - detects if image is clipart or a line drawing. Color - determines the accent color, dominant color, and
// whether an image is black&white.Adult - detects if the image is pornographic in nature (depicts nudity or a sex
// act).  Sexually suggestive content is also detected. details is a string indicating which domain-specific details to
// return. Multiple values should be comma-separated. Valid visual feature types include:Celebrities - identifies
// celebrities if detected in the image. language is a string indicating which language to return. The service will
// return recognition results in specified language. If this parameter is not specified, the default value is
// &quot;en&quot;.Supported languages:en - English, Default.zh - Simplified Chinese.
func (client BaseClient) AnalyzeImage(ctx context.Context, imageURL ImageURL, visualFeatures []VisualFeatureTypes, details []Details, language Language1) (result ImageAnalysis, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "AnalyzeImage")
	}

	req, err := client.AnalyzeImagePreparer(ctx, imageURL, visualFeatures, details, language)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImage", nil, "Failure preparing request")
		return
	}

	resp, err := client.AnalyzeImageSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImage", resp, "Failure sending request")
		return
	}

	result, err = client.AnalyzeImageResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImage", resp, "Failure responding to request")
	}

	return
}

// AnalyzeImagePreparer prepares the AnalyzeImage request.
func (client BaseClient) AnalyzeImagePreparer(ctx context.Context, imageURL ImageURL, visualFeatures []VisualFeatureTypes, details []Details, language Language1) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if visualFeatures != nil && len(visualFeatures) > 0 {
		queryParameters["visualFeatures"] = autorest.Encode("query", visualFeatures, ",")
	}
	if details != nil && len(details) > 0 {
		queryParameters["details"] = autorest.Encode("query", details, ",")
	}
	if len(string(language)) > 0 {
		queryParameters["language"] = autorest.Encode("query", language)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/analyze"),
		autorest.WithJSON(imageURL),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// AnalyzeImageSender sends the AnalyzeImage request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) AnalyzeImageSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// AnalyzeImageResponder handles the response to the AnalyzeImage request. The method always
// closes the http.Response Body.
func (client BaseClient) AnalyzeImageResponder(resp *http.Response) (result ImageAnalysis, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// AnalyzeImageByDomain this operation recognizes content within an image by applying a domain-specific model.  The
// list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models GET
// request.  Currently, the API only provides a single domain-specific model: celebrities. Two input methods are
// supported -- (1) Uploading an image or (2) specifying an image URL. A successful response will be returned in JSON.
// If the request failed, the response will contain an error code and a message to help understand what went wrong.
//
// model is the domain-specific content to recognize. imageURL is a JSON document with a URL pointing to the image that
// is to be analyzed.
func (client BaseClient) AnalyzeImageByDomain(ctx context.Context, model DomainModels, imageURL ImageURL) (result DomainModelResults, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "AnalyzeImageByDomain")
	}

	req, err := client.AnalyzeImageByDomainPreparer(ctx, model, imageURL)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomain", nil, "Failure preparing request")
		return
	}

	resp, err := client.AnalyzeImageByDomainSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomain", resp, "Failure sending request")
		return
	}

	result, err = client.AnalyzeImageByDomainResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomain", resp, "Failure responding to request")
	}

	return
}

// AnalyzeImageByDomainPreparer prepares the AnalyzeImageByDomain request.
func (client BaseClient) AnalyzeImageByDomainPreparer(ctx context.Context, model DomainModels, imageURL ImageURL) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	pathParameters := map[string]interface{}{
		"model": autorest.Encode("path", model),
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPathParameters("/models/{model}/analyze", pathParameters),
		autorest.WithJSON(imageURL))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// AnalyzeImageByDomainSender sends the AnalyzeImageByDomain request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) AnalyzeImageByDomainSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// AnalyzeImageByDomainResponder handles the response to the AnalyzeImageByDomain request. The method always
// closes the http.Response Body.
func (client BaseClient) AnalyzeImageByDomainResponder(resp *http.Response) (result DomainModelResults, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// AnalyzeImageByDomainInStream this operation recognizes content within an image by applying a domain-specific model.
// The list of domain-specific models that are supported by the Computer Vision API can be retrieved using the /models
// GET request.  Currently, the API only provides a single domain-specific model: celebrities. Two input methods are
// supported -- (1) Uploading an image or (2) specifying an image URL. A successful response will be returned in JSON.
// If the request failed, the response will contain an error code and a message to help understand what went wrong.
//
// model is the domain-specific content to recognize. imageParameter is an image stream. imageParameter will be closed
// upon successful return. Callers should ensure closure when receiving an error.
func (client BaseClient) AnalyzeImageByDomainInStream(ctx context.Context, model string, imageParameter io.ReadCloser) (result DomainModelResults, err error) {
	req, err := client.AnalyzeImageByDomainInStreamPreparer(ctx, model, imageParameter)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomainInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.AnalyzeImageByDomainInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomainInStream", resp, "Failure sending request")
		return
	}

	result, err = client.AnalyzeImageByDomainInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageByDomainInStream", resp, "Failure responding to request")
	}

	return
}

// AnalyzeImageByDomainInStreamPreparer prepares the AnalyzeImageByDomainInStream request.
func (client BaseClient) AnalyzeImageByDomainInStreamPreparer(ctx context.Context, model string, imageParameter io.ReadCloser) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	pathParameters := map[string]interface{}{
		"model": autorest.Encode("path", model),
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPathParameters("/models/{model}/analyze", pathParameters),
		autorest.WithFile(imageParameter))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// AnalyzeImageByDomainInStreamSender sends the AnalyzeImageByDomainInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) AnalyzeImageByDomainInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// AnalyzeImageByDomainInStreamResponder handles the response to the AnalyzeImageByDomainInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) AnalyzeImageByDomainInStreamResponder(resp *http.Response) (result DomainModelResults, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// AnalyzeImageInStream this operation extracts a rich set of visual features based on the image content.
//
// imageParameter is an image stream. imageParameter will be closed upon successful return. Callers should ensure
// closure when receiving an error.visualFeatures is a string indicating what visual feature types to return. Multiple
// values should be comma-separated. Valid visual feature types include:Categories - categorizes image content
// according to a taxonomy defined in documentation. Tags - tags the image with a detailed list of words related to the
// image content. Description - describes the image content with a complete English sentence. Faces - detects if faces
// are present. If present, generate coordinates, gender and age. ImageType - detects if image is clipart or a line
// drawing. Color - determines the accent color, dominant color, and whether an image is black&white.Adult - detects if
// the image is pornographic in nature (depicts nudity or a sex act).  Sexually suggestive content is also detected.
// details is a string indicating which domain-specific details to return. Multiple values should be comma-separated.
// Valid visual feature types include:Celebrities - identifies celebrities if detected in the image. language is a
// string indicating which language to return. The service will return recognition results in specified language. If
// this parameter is not specified, the default value is &quot;en&quot;.Supported languages:en - English, Default.zh -
// Simplified Chinese.
func (client BaseClient) AnalyzeImageInStream(ctx context.Context, imageParameter io.ReadCloser, visualFeatures []VisualFeatureTypes, details string, language string) (result ImageAnalysis, err error) {
	req, err := client.AnalyzeImageInStreamPreparer(ctx, imageParameter, visualFeatures, details, language)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.AnalyzeImageInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageInStream", resp, "Failure sending request")
		return
	}

	result, err = client.AnalyzeImageInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "AnalyzeImageInStream", resp, "Failure responding to request")
	}

	return
}

// AnalyzeImageInStreamPreparer prepares the AnalyzeImageInStream request.
func (client BaseClient) AnalyzeImageInStreamPreparer(ctx context.Context, imageParameter io.ReadCloser, visualFeatures []VisualFeatureTypes, details string, language string) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if visualFeatures != nil && len(visualFeatures) > 0 {
		queryParameters["visualFeatures"] = autorest.Encode("query", visualFeatures, ",")
	}
	if len(string(details)) > 0 {
		queryParameters["details"] = autorest.Encode("query", details)
	}
	if len(string(language)) > 0 {
		queryParameters["language"] = autorest.Encode("query", language)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/analyze"),
		autorest.WithFile(imageParameter),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// AnalyzeImageInStreamSender sends the AnalyzeImageInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) AnalyzeImageInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// AnalyzeImageInStreamResponder handles the response to the AnalyzeImageInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) AnalyzeImageInStreamResponder(resp *http.Response) (result ImageAnalysis, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// DescribeImage this operation generates a description of an image in human readable language with complete sentences.
// The description is based on a collection of content tags, which are also returned by the operation. More than one
// description can be generated for each image.  Descriptions are ordered by their confidence score. All descriptions
// are in English. Two input methods are supported -- (1) Uploading an image or (2) specifying an image URL.A
// successful response will be returned in JSON.  If the request failed, the response will contain an error code and a
// message to help understand what went wrong.
//
// imageURL is a JSON document with a URL pointing to the image that is to be analyzed. maxCandidates is maximum number
// of candidate descriptions to be returned.  The default is 1.
func (client BaseClient) DescribeImage(ctx context.Context, imageURL ImageURL, maxCandidates string) (result ImageDescription, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "DescribeImage")
	}

	req, err := client.DescribeImagePreparer(ctx, imageURL, maxCandidates)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImage", nil, "Failure preparing request")
		return
	}

	resp, err := client.DescribeImageSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImage", resp, "Failure sending request")
		return
	}

	result, err = client.DescribeImageResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImage", resp, "Failure responding to request")
	}

	return
}

// DescribeImagePreparer prepares the DescribeImage request.
func (client BaseClient) DescribeImagePreparer(ctx context.Context, imageURL ImageURL, maxCandidates string) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if len(maxCandidates) > 0 {
		queryParameters["maxCandidates"] = autorest.Encode("query", maxCandidates)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/describe"),
		autorest.WithJSON(imageURL),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// DescribeImageSender sends the DescribeImage request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) DescribeImageSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// DescribeImageResponder handles the response to the DescribeImage request. The method always
// closes the http.Response Body.
func (client BaseClient) DescribeImageResponder(resp *http.Response) (result ImageDescription, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// DescribeImageInStream this operation generates a description of an image in human readable language with complete
// sentences.  The description is based on a collection of content tags, which are also returned by the operation. More
// than one description can be generated for each image.  Descriptions are ordered by their confidence score. All
// descriptions are in English. Two input methods are supported -- (1) Uploading an image or (2) specifying an image
// URL.A successful response will be returned in JSON.  If the request failed, the response will contain an error code
// and a message to help understand what went wrong.
//
// imageParameter is an image stream. imageParameter will be closed upon successful return. Callers should ensure
// closure when receiving an error.maxCandidates is maximum number of candidate descriptions to be returned.  The
// default is 1.
func (client BaseClient) DescribeImageInStream(ctx context.Context, imageParameter io.ReadCloser, maxCandidates string) (result ImageDescription, err error) {
	req, err := client.DescribeImageInStreamPreparer(ctx, imageParameter, maxCandidates)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImageInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.DescribeImageInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImageInStream", resp, "Failure sending request")
		return
	}

	result, err = client.DescribeImageInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "DescribeImageInStream", resp, "Failure responding to request")
	}

	return
}

// DescribeImageInStreamPreparer prepares the DescribeImageInStream request.
func (client BaseClient) DescribeImageInStreamPreparer(ctx context.Context, imageParameter io.ReadCloser, maxCandidates string) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if len(maxCandidates) > 0 {
		queryParameters["maxCandidates"] = autorest.Encode("query", maxCandidates)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/describe"),
		autorest.WithFile(imageParameter),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// DescribeImageInStreamSender sends the DescribeImageInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) DescribeImageInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// DescribeImageInStreamResponder handles the response to the DescribeImageInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) DescribeImageInStreamResponder(resp *http.Response) (result ImageDescription, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// GenerateThumbnail this operation generates a thumbnail image with the user-specified width and height. By default,
// the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping coordinates
// based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the input image. A
// successful response contains the thumbnail image binary. If the request failed, the response contains an error code
// and a message to help determine what went wrong.
//
// width is width of the thumbnail. It must be between 1 and 1024. Recommended minimum of 50. height is height of the
// thumbnail. It must be between 1 and 1024. Recommended minimum of 50. imageURL is a JSON document with a URL pointing
// to the image that is to be analyzed. smartCropping is boolean flag for enabling smart cropping.
func (client BaseClient) GenerateThumbnail(ctx context.Context, width int32, height int32, imageURL ImageURL, smartCropping *bool) (result ReadCloser, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: width,
			Constraints: []validation.Constraint{{Target: "width", Name: validation.InclusiveMaximum, Rule: 1023, Chain: nil},
				{Target: "width", Name: validation.InclusiveMinimum, Rule: 1, Chain: nil}}},
		{TargetValue: height,
			Constraints: []validation.Constraint{{Target: "height", Name: validation.InclusiveMaximum, Rule: 1023, Chain: nil},
				{Target: "height", Name: validation.InclusiveMinimum, Rule: 1, Chain: nil}}},
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "GenerateThumbnail")
	}

	req, err := client.GenerateThumbnailPreparer(ctx, width, height, imageURL, smartCropping)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnail", nil, "Failure preparing request")
		return
	}

	resp, err := client.GenerateThumbnailSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnail", resp, "Failure sending request")
		return
	}

	result, err = client.GenerateThumbnailResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnail", resp, "Failure responding to request")
	}

	return
}

// GenerateThumbnailPreparer prepares the GenerateThumbnail request.
func (client BaseClient) GenerateThumbnailPreparer(ctx context.Context, width int32, height int32, imageURL ImageURL, smartCropping *bool) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{
		"height": autorest.Encode("query", height),
		"width":  autorest.Encode("query", width),
	}
	if smartCropping != nil {
		queryParameters["smartCropping"] = autorest.Encode("query", *smartCropping)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/generateThumbnail"),
		autorest.WithJSON(imageURL),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GenerateThumbnailSender sends the GenerateThumbnail request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) GenerateThumbnailSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// GenerateThumbnailResponder handles the response to the GenerateThumbnail request. The method always
// closes the http.Response Body.
func (client BaseClient) GenerateThumbnailResponder(resp *http.Response) (result ReadCloser, err error) {
	result.Value = &resp.Body
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK))
	result.Response = autorest.Response{Response: resp}
	return
}

// GenerateThumbnailInStream this operation generates a thumbnail image with the user-specified width and height. By
// default, the service analyzes the image, identifies the region of interest (ROI), and generates smart cropping
// coordinates based on the ROI. Smart cropping helps when you specify an aspect ratio that differs from that of the
// input image. A successful response contains the thumbnail image binary. If the request failed, the response contains
// an error code and a message to help determine what went wrong.
//
// width is width of the thumbnail. It must be between 1 and 1024. Recommended minimum of 50. height is height of the
// thumbnail. It must be between 1 and 1024. Recommended minimum of 50. imageParameter is an image stream.
// imageParameter will be closed upon successful return. Callers should ensure closure when receiving an
// error.smartCropping is boolean flag for enabling smart cropping.
func (client BaseClient) GenerateThumbnailInStream(ctx context.Context, width int32, height int32, imageParameter io.ReadCloser, smartCropping *bool) (result ReadCloser, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: width,
			Constraints: []validation.Constraint{{Target: "width", Name: validation.InclusiveMaximum, Rule: 1023, Chain: nil},
				{Target: "width", Name: validation.InclusiveMinimum, Rule: 1, Chain: nil}}},
		{TargetValue: height,
			Constraints: []validation.Constraint{{Target: "height", Name: validation.InclusiveMaximum, Rule: 1023, Chain: nil},
				{Target: "height", Name: validation.InclusiveMinimum, Rule: 1, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "GenerateThumbnailInStream")
	}

	req, err := client.GenerateThumbnailInStreamPreparer(ctx, width, height, imageParameter, smartCropping)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnailInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.GenerateThumbnailInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnailInStream", resp, "Failure sending request")
		return
	}

	result, err = client.GenerateThumbnailInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GenerateThumbnailInStream", resp, "Failure responding to request")
	}

	return
}

// GenerateThumbnailInStreamPreparer prepares the GenerateThumbnailInStream request.
func (client BaseClient) GenerateThumbnailInStreamPreparer(ctx context.Context, width int32, height int32, imageParameter io.ReadCloser, smartCropping *bool) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{
		"height": autorest.Encode("query", height),
		"width":  autorest.Encode("query", width),
	}
	if smartCropping != nil {
		queryParameters["smartCropping"] = autorest.Encode("query", *smartCropping)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/generateThumbnail"),
		autorest.WithFile(imageParameter),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GenerateThumbnailInStreamSender sends the GenerateThumbnailInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) GenerateThumbnailInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// GenerateThumbnailInStreamResponder handles the response to the GenerateThumbnailInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) GenerateThumbnailInStreamResponder(resp *http.Response) (result ReadCloser, err error) {
	result.Value = &resp.Body
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK))
	result.Response = autorest.Response{Response: resp}
	return
}

// GetTextOperationResult this interface is used for getting text operation result. The URL to this interface should be
// retrieved from 'Operation-Location' field returned from Recognize Text interface.
//
// operationID is id of the text operation returned in the response of the 'Recognize Handwritten Text'
func (client BaseClient) GetTextOperationResult(ctx context.Context, operationID string) (result TextOperationResult, err error) {
	req, err := client.GetTextOperationResultPreparer(ctx, operationID)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GetTextOperationResult", nil, "Failure preparing request")
		return
	}

	resp, err := client.GetTextOperationResultSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GetTextOperationResult", resp, "Failure sending request")
		return
	}

	result, err = client.GetTextOperationResultResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "GetTextOperationResult", resp, "Failure responding to request")
	}

	return
}

// GetTextOperationResultPreparer prepares the GetTextOperationResult request.
func (client BaseClient) GetTextOperationResultPreparer(ctx context.Context, operationID string) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	pathParameters := map[string]interface{}{
		"operationId": autorest.Encode("path", operationID),
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPathParameters("/textOperations/{operationId}", pathParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// GetTextOperationResultSender sends the GetTextOperationResult request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) GetTextOperationResultSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// GetTextOperationResultResponder handles the response to the GetTextOperationResult request. The method always
// closes the http.Response Body.
func (client BaseClient) GetTextOperationResultResponder(resp *http.Response) (result TextOperationResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// ListModels this operation returns the list of domain-specific models that are supported by the Computer Vision API.
// Currently, the API only supports one domain-specific model: a celebrity recognizer. A successful response will be
// returned in JSON.  If the request failed, the response will contain an error code and a message to help understand
// what went wrong.
func (client BaseClient) ListModels(ctx context.Context) (result ListModelsResult, err error) {
	req, err := client.ListModelsPreparer(ctx)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "ListModels", nil, "Failure preparing request")
		return
	}

	resp, err := client.ListModelsSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "ListModels", resp, "Failure sending request")
		return
	}

	result, err = client.ListModelsResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "ListModels", resp, "Failure responding to request")
	}

	return
}

// ListModelsPreparer prepares the ListModels request.
func (client BaseClient) ListModelsPreparer(ctx context.Context) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/models"))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// ListModelsSender sends the ListModels request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) ListModelsSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// ListModelsResponder handles the response to the ListModels request. The method always
// closes the http.Response Body.
func (client BaseClient) ListModelsResponder(resp *http.Response) (result ListModelsResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// RecognizePrintedText optical Character Recognition (OCR) detects printed text in an image and extracts the
// recognized characters into a machine-usable character stream.   Upon success, the OCR results will be returned. Upon
// failure, the error code together with an error message will be returned. The error code can be one of
// InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage,  NotSupportedLanguage, or
// InternalServerError.
//
// detectOrientation is whether detect the text orientation in the image. With detectOrientation=true the OCR service
// tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down). imageURL
// is a JSON document with a URL pointing to the image that is to be analyzed. language is the BCP-47 language code of
// the text to be detected in the image. The default value is 'unk'
func (client BaseClient) RecognizePrintedText(ctx context.Context, detectOrientation bool, imageURL ImageURL, language OcrLanguages) (result OcrResult, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "RecognizePrintedText")
	}

	req, err := client.RecognizePrintedTextPreparer(ctx, detectOrientation, imageURL, language)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedText", nil, "Failure preparing request")
		return
	}

	resp, err := client.RecognizePrintedTextSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedText", resp, "Failure sending request")
		return
	}

	result, err = client.RecognizePrintedTextResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedText", resp, "Failure responding to request")
	}

	return
}

// RecognizePrintedTextPreparer prepares the RecognizePrintedText request.
func (client BaseClient) RecognizePrintedTextPreparer(ctx context.Context, detectOrientation bool, imageURL ImageURL, language OcrLanguages) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{
		"detectOrientation": autorest.Encode("query", detectOrientation),
	}
	if len(string(language)) > 0 {
		queryParameters["language"] = autorest.Encode("query", language)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/ocr"),
		autorest.WithJSON(imageURL),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// RecognizePrintedTextSender sends the RecognizePrintedText request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) RecognizePrintedTextSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// RecognizePrintedTextResponder handles the response to the RecognizePrintedText request. The method always
// closes the http.Response Body.
func (client BaseClient) RecognizePrintedTextResponder(resp *http.Response) (result OcrResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// RecognizePrintedTextInStream optical Character Recognition (OCR) detects printed text in an image and extracts the
// recognized characters into a machine-usable character stream.   Upon success, the OCR results will be returned. Upon
// failure, the error code together with an error message will be returned. The error code can be one of
// InvalidImageUrl, InvalidImageFormat, InvalidImageSize, NotSupportedImage,  NotSupportedLanguage, or
// InternalServerError.
//
// detectOrientation is whether detect the text orientation in the image. With detectOrientation=true the OCR service
// tries to detect the image orientation and correct it before further processing (e.g. if it's upside-down).
// imageParameter is an image stream. imageParameter will be closed upon successful return. Callers should ensure
// closure when receiving an error.language is the BCP-47 language code of the text to be detected in the image. The
// default value is 'unk'
func (client BaseClient) RecognizePrintedTextInStream(ctx context.Context, detectOrientation bool, imageParameter io.ReadCloser, language OcrLanguages) (result OcrResult, err error) {
	req, err := client.RecognizePrintedTextInStreamPreparer(ctx, detectOrientation, imageParameter, language)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedTextInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.RecognizePrintedTextInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedTextInStream", resp, "Failure sending request")
		return
	}

	result, err = client.RecognizePrintedTextInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizePrintedTextInStream", resp, "Failure responding to request")
	}

	return
}

// RecognizePrintedTextInStreamPreparer prepares the RecognizePrintedTextInStream request.
func (client BaseClient) RecognizePrintedTextInStreamPreparer(ctx context.Context, detectOrientation bool, imageParameter io.ReadCloser, language OcrLanguages) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{
		"detectOrientation": autorest.Encode("query", detectOrientation),
	}
	if len(string(language)) > 0 {
		queryParameters["language"] = autorest.Encode("query", language)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/ocr"),
		autorest.WithFile(imageParameter),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// RecognizePrintedTextInStreamSender sends the RecognizePrintedTextInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) RecognizePrintedTextInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// RecognizePrintedTextInStreamResponder handles the response to the RecognizePrintedTextInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) RecognizePrintedTextInStreamResponder(resp *http.Response) (result OcrResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// RecognizeText recognize Text operation. When you use the Recognize Text interface, the response contains a field
// called “Operation-Location”. The “Operation-Location” field contains the URL that you must use for your Get
// Handwritten Text Operation Result operation.
//
// imageURL is a JSON document with a URL pointing to the image that is to be analyzed. detectHandwriting is if “true”
// is specified, handwriting recognition is performed. If this parameter is set to “false” or is not specified, printed
// text recognition is performed.
func (client BaseClient) RecognizeText(ctx context.Context, imageURL ImageURL, detectHandwriting *bool) (result autorest.Response, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "RecognizeText")
	}

	req, err := client.RecognizeTextPreparer(ctx, imageURL, detectHandwriting)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeText", nil, "Failure preparing request")
		return
	}

	resp, err := client.RecognizeTextSender(req)
	if err != nil {
		result.Response = resp
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeText", resp, "Failure sending request")
		return
	}

	result, err = client.RecognizeTextResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeText", resp, "Failure responding to request")
	}

	return
}

// RecognizeTextPreparer prepares the RecognizeText request.
func (client BaseClient) RecognizeTextPreparer(ctx context.Context, imageURL ImageURL, detectHandwriting *bool) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if detectHandwriting != nil {
		queryParameters["detectHandwriting"] = autorest.Encode("query", *detectHandwriting)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/recognizeText"),
		autorest.WithJSON(imageURL),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// RecognizeTextSender sends the RecognizeText request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) RecognizeTextSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// RecognizeTextResponder handles the response to the RecognizeText request. The method always
// closes the http.Response Body.
func (client BaseClient) RecognizeTextResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
		autorest.ByClosing())
	result.Response = resp
	return
}

// RecognizeTextInStream recognize Text operation. When you use the Recognize Text interface, the response contains a
// field called “Operation-Location”. The “Operation-Location” field contains the URL that you must use for your Get
// Handwritten Text Operation Result operation.
//
// imageParameter is an image stream. imageParameter will be closed upon successful return. Callers should ensure
// closure when receiving an error.detectHandwriting is if “true” is specified, handwriting recognition is performed.
// If this parameter is set to “false” or is not specified, printed text recognition is performed.
func (client BaseClient) RecognizeTextInStream(ctx context.Context, imageParameter io.ReadCloser, detectHandwriting *bool) (result autorest.Response, err error) {
	req, err := client.RecognizeTextInStreamPreparer(ctx, imageParameter, detectHandwriting)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeTextInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.RecognizeTextInStreamSender(req)
	if err != nil {
		result.Response = resp
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeTextInStream", resp, "Failure sending request")
		return
	}

	result, err = client.RecognizeTextInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "RecognizeTextInStream", resp, "Failure responding to request")
	}

	return
}

// RecognizeTextInStreamPreparer prepares the RecognizeTextInStream request.
func (client BaseClient) RecognizeTextInStreamPreparer(ctx context.Context, imageParameter io.ReadCloser, detectHandwriting *bool) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	queryParameters := map[string]interface{}{}
	if detectHandwriting != nil {
		queryParameters["detectHandwriting"] = autorest.Encode("query", *detectHandwriting)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/recognizeText"),
		autorest.WithFile(imageParameter),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// RecognizeTextInStreamSender sends the RecognizeTextInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) RecognizeTextInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// RecognizeTextInStreamResponder handles the response to the RecognizeTextInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) RecognizeTextInStreamResponder(resp *http.Response) (result autorest.Response, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK, http.StatusAccepted),
		autorest.ByClosing())
	result.Response = resp
	return
}

// TagImage this operation generates a list of words, or tags, that are relevant to the content of the supplied image.
// The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images. Unlike
// categories, tags are not organized according to a hierarchical classification system, but correspond to image
// content. Tags may contain hints to avoid ambiguity or provide context, for example the tag “cello” may be
// accompanied by the hint “musical instrument”. All tags are in English.
//
// imageURL is a JSON document with a URL pointing to the image that is to be analyzed.
func (client BaseClient) TagImage(ctx context.Context, imageURL ImageURL) (result TagResult, err error) {
	if err := validation.Validate([]validation.Validation{
		{TargetValue: imageURL,
			Constraints: []validation.Constraint{{Target: "imageURL.URL", Name: validation.Null, Rule: true, Chain: nil}}}}); err != nil {
		return result, validation.NewErrorWithValidationError(err, "computervision.BaseClient", "TagImage")
	}

	req, err := client.TagImagePreparer(ctx, imageURL)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImage", nil, "Failure preparing request")
		return
	}

	resp, err := client.TagImageSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImage", resp, "Failure sending request")
		return
	}

	result, err = client.TagImageResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImage", resp, "Failure responding to request")
	}

	return
}

// TagImagePreparer prepares the TagImage request.
func (client BaseClient) TagImagePreparer(ctx context.Context, imageURL ImageURL) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/tag"),
		autorest.WithJSON(imageURL))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// TagImageSender sends the TagImage request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) TagImageSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// TagImageResponder handles the response to the TagImage request. The method always
// closes the http.Response Body.
func (client BaseClient) TagImageResponder(resp *http.Response) (result TagResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}

// TagImageInStream this operation generates a list of words, or tags, that are relevant to the content of the supplied
// image. The Computer Vision API can return tags based on objects, living beings, scenery or actions found in images.
// Unlike categories, tags are not organized according to a hierarchical classification system, but correspond to image
// content. Tags may contain hints to avoid ambiguity or provide context, for example the tag “cello” may be
// accompanied by the hint “musical instrument”. All tags are in English.
//
// imageParameter is an image stream. imageParameter will be closed upon successful return. Callers should ensure
// closure when receiving an error.
func (client BaseClient) TagImageInStream(ctx context.Context, imageParameter io.ReadCloser) (result TagResult, err error) {
	req, err := client.TagImageInStreamPreparer(ctx, imageParameter)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImageInStream", nil, "Failure preparing request")
		return
	}

	resp, err := client.TagImageInStreamSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImageInStream", resp, "Failure sending request")
		return
	}

	result, err = client.TagImageInStreamResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "computervision.BaseClient", "TagImageInStream", resp, "Failure responding to request")
	}

	return
}

// TagImageInStreamPreparer prepares the TagImageInStream request.
func (client BaseClient) TagImageInStreamPreparer(ctx context.Context, imageParameter io.ReadCloser) (*http.Request, error) {
	urlParameters := map[string]interface{}{
		"AzureRegion": client.AzureRegion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsPost(),
		autorest.WithCustomBaseURL("https://{AzureRegion}.api.cognitive.microsoft.com/vision/v1.0", urlParameters),
		autorest.WithPath("/tag"),
		autorest.WithFile(imageParameter))
	return preparer.Prepare((&http.Request{}).WithContext(ctx))
}

// TagImageInStreamSender sends the TagImageInStream request. The method will close the
// http.Response Body if it receives an error.
func (client BaseClient) TagImageInStreamSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
}

// TagImageInStreamResponder handles the response to the TagImageInStream request. The method always
// closes the http.Response Body.
func (client BaseClient) TagImageInStreamResponder(resp *http.Response) (result TagResult, err error) {
	err = autorest.Respond(
		resp,
		client.ByInspecting(),
		azure.WithErrorUnlessStatusCode(http.StatusOK),
		autorest.ByUnmarshallingJSON(&result),
		autorest.ByClosing())
	result.Response = autorest.Response{Response: resp}
	return
}
