package mobileengagement

// 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 0.17.0.0
// Changes may cause incorrect behavior and will be lost if the code is
// regenerated.

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

// DevicesClient is the microsoft Azure Mobile Engagement REST APIs.
type DevicesClient struct {
	ManagementClient
}

// NewDevicesClient creates an instance of the DevicesClient client.
func NewDevicesClient(subscriptionID string, resourceGroupName string, appCollection string, appName string) DevicesClient {
	return NewDevicesClientWithBaseURI(DefaultBaseURI, subscriptionID, resourceGroupName, appCollection, appName)
}

// NewDevicesClientWithBaseURI creates an instance of the DevicesClient client.
func NewDevicesClientWithBaseURI(baseURI string, subscriptionID string, resourceGroupName string, appCollection string, appName string) DevicesClient {
	return DevicesClient{NewWithBaseURI(baseURI, subscriptionID, resourceGroupName, appCollection, appName)}
}

// GetByDeviceID get the information associated to a device running an
// application.
//
// deviceID is device identifier.
func (client DevicesClient) GetByDeviceID(deviceID string) (result Device, err error) {
	req, err := client.GetByDeviceIDPreparer(deviceID)
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByDeviceID", nil, "Failure preparing request")
	}

	resp, err := client.GetByDeviceIDSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByDeviceID", resp, "Failure sending request")
	}

	result, err = client.GetByDeviceIDResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByDeviceID", resp, "Failure responding to request")
	}

	return
}

// GetByDeviceIDPreparer prepares the GetByDeviceID request.
func (client DevicesClient) GetByDeviceIDPreparer(deviceID string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"appCollection":     autorest.Encode("path", client.AppCollection),
		"appName":           autorest.Encode("path", client.AppName),
		"deviceId":          autorest.Encode("path", deviceID),
		"resourceGroupName": autorest.Encode("path", client.ResourceGroupName),
		"subscriptionId":    autorest.Encode("path", client.SubscriptionID),
	}

	queryParameters := map[string]interface{}{
		"api-version": client.APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MobileEngagement/appcollections/{appCollection}/apps/{appName}/devices/{deviceId}", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare(&http.Request{})
}

// GetByDeviceIDSender sends the GetByDeviceID request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) GetByDeviceIDSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req)
}

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

// GetByUserID get the information associated to a device running an
// application using the user identifier.
//
// userID is user identifier.
func (client DevicesClient) GetByUserID(userID string) (result Device, err error) {
	req, err := client.GetByUserIDPreparer(userID)
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByUserID", nil, "Failure preparing request")
	}

	resp, err := client.GetByUserIDSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByUserID", resp, "Failure sending request")
	}

	result, err = client.GetByUserIDResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "GetByUserID", resp, "Failure responding to request")
	}

	return
}

// GetByUserIDPreparer prepares the GetByUserID request.
func (client DevicesClient) GetByUserIDPreparer(userID string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"appCollection":     autorest.Encode("path", client.AppCollection),
		"appName":           autorest.Encode("path", client.AppName),
		"resourceGroupName": autorest.Encode("path", client.ResourceGroupName),
		"subscriptionId":    autorest.Encode("path", client.SubscriptionID),
		"userId":            autorest.Encode("path", userID),
	}

	queryParameters := map[string]interface{}{
		"api-version": client.APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MobileEngagement/appcollections/{appCollection}/apps/{appName}/users/{userId}", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare(&http.Request{})
}

// GetByUserIDSender sends the GetByUserID request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) GetByUserIDSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req)
}

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

// List query the information associated to the devices running an application.
//
// top is number of devices to return with each call. Defaults to 100 and
// cannot return more. Passing a greater value is ignored. The response
// contains a `nextLink` property describing the URI path to get the next
// page of results if not all results could be returned at once.
// selectParameter is by default all `meta` and `appInfo` properties are
// returned, this property is used to restrict the output to the desired
// properties. It also excludes all devices from the output that have none of
// the selected properties. In other terms, only devices having at least one
// of the selected property being set is part of the results. Examples: -
// `$select=appInfo` : select all devices having at least 1 appInfo, return
// them all and don’t return any meta property. - `$select=meta` : return
// only meta properties in the output. -
// `$select=appInfo,meta/firstSeen,meta/lastSeen` : return all `appInfo`,
// plus meta object containing only firstSeen and lastSeen properties. The
// format is thus a comma separated list of properties to select. Use
// `appInfo` to select all appInfo properties, `meta` to select all meta
// properties. Use `appInfo/{key}` and `meta/{key}` to select specific
// appInfo and meta properties. filter is filter can be used to reduce the
// number of results. Filter is a boolean expression that can look like the
// following examples: * `$filter=deviceId gt
// 'abcdef0123456789abcdef0123456789'` * `$filter=lastModified le
// 1447284263690L` * `$filter=(deviceId ge
// 'abcdef0123456789abcdef0123456789') and (deviceId lt
// 'bacdef0123456789abcdef0123456789') and (lastModified gt 1447284263690L)`
// The first example is used automatically for paging when returning the
// `nextLink` property. The filter expression is a combination of checks on
// some properties that can be compared to their value. The available
// operators are: * `gt`  : greater than * `ge`  : greater than or equals *
// `lt`  : less than * `le`  : less than or equals * `and` : to add multiple
// checks (all checks must pass), optional parentheses can be used. The
// properties that can be used in the expression are the following: *
// `deviceId {operator} '{deviceIdValue}'` : a lexicographical comparison is
// made on the deviceId value, use single quotes for the value. *
// `lastModified {operator} {number}L` : returns only meta properties or
// appInfo properties whose last value modification timestamp compared to the
// specified value is matching (value is milliseconds since January 1st, 1970
// UTC). Please note the `L` character after the number of milliseconds, its
// required when the number of milliseconds exceeds `2^31 - 1` (which is
// always the case for recent timestamps). Using `lastModified` excludes all
// devices from the output that have no property matching the timestamp
// criteria, like `$select`. Please note that the internal value of
// `lastModified` timestamp for a given property is never part of the
// results.
func (client DevicesClient) List(top *int32, selectParameter string, filter string) (result DevicesQueryResult, err error) {
	req, err := client.ListPreparer(top, selectParameter, filter)
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", nil, "Failure preparing request")
	}

	resp, err := client.ListSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", resp, "Failure sending request")
	}

	result, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", resp, "Failure responding to request")
	}

	return
}

// ListPreparer prepares the List request.
func (client DevicesClient) ListPreparer(top *int32, selectParameter string, filter string) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"appCollection":     autorest.Encode("path", client.AppCollection),
		"appName":           autorest.Encode("path", client.AppName),
		"resourceGroupName": autorest.Encode("path", client.ResourceGroupName),
		"subscriptionId":    autorest.Encode("path", client.SubscriptionID),
	}

	queryParameters := map[string]interface{}{
		"api-version": client.APIVersion,
	}
	if top != nil {
		queryParameters["$top"] = autorest.Encode("query", *top)
	}
	if len(selectParameter) > 0 {
		queryParameters["$select"] = autorest.Encode("query", selectParameter)
	}
	if len(filter) > 0 {
		queryParameters["$filter"] = autorest.Encode("query", filter)
	}

	preparer := autorest.CreatePreparer(
		autorest.AsGet(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MobileEngagement/appcollections/{appCollection}/apps/{appName}/devices", pathParameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare(&http.Request{})
}

// ListSender sends the List request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) ListSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req)
}

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

// ListNextResults retrieves the next set of results, if any.
func (client DevicesClient) ListNextResults(lastResults DevicesQueryResult) (result DevicesQueryResult, err error) {
	req, err := lastResults.DevicesQueryResultPreparer()
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", nil, "Failure preparing next results request request")
	}
	if req == nil {
		return
	}

	resp, err := client.ListSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", resp, "Failure sending next results request request")
	}

	result, err = client.ListResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "List", resp, "Failure responding to next results request request")
	}

	return
}

// TagByDeviceID update the tags registered for a set of devices running an
// application. Updates are performed asynchronously, meaning that a few
// seconds are needed before the modifications appear in the results of the
// Get device command.
//
func (client DevicesClient) TagByDeviceID(parameters DeviceTagsParameters) (result DeviceTagsResult, err error) {
	req, err := client.TagByDeviceIDPreparer(parameters)
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByDeviceID", nil, "Failure preparing request")
	}

	resp, err := client.TagByDeviceIDSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByDeviceID", resp, "Failure sending request")
	}

	result, err = client.TagByDeviceIDResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByDeviceID", resp, "Failure responding to request")
	}

	return
}

// TagByDeviceIDPreparer prepares the TagByDeviceID request.
func (client DevicesClient) TagByDeviceIDPreparer(parameters DeviceTagsParameters) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"appCollection":     autorest.Encode("path", client.AppCollection),
		"appName":           autorest.Encode("path", client.AppName),
		"resourceGroupName": autorest.Encode("path", client.ResourceGroupName),
		"subscriptionId":    autorest.Encode("path", client.SubscriptionID),
	}

	queryParameters := map[string]interface{}{
		"api-version": client.APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MobileEngagement/appcollections/{appCollection}/apps/{appName}/devices/tag", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare(&http.Request{})
}

// TagByDeviceIDSender sends the TagByDeviceID request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) TagByDeviceIDSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req)
}

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

// TagByUserID update the tags registered for a set of users running an
// application. Updates are performed asynchronously, meaning that a few
// seconds are needed before the modifications appear in the results of the
// Get device command.
//
func (client DevicesClient) TagByUserID(parameters DeviceTagsParameters) (result DeviceTagsResult, err error) {
	req, err := client.TagByUserIDPreparer(parameters)
	if err != nil {
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByUserID", nil, "Failure preparing request")
	}

	resp, err := client.TagByUserIDSender(req)
	if err != nil {
		result.Response = autorest.Response{Response: resp}
		return result, autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByUserID", resp, "Failure sending request")
	}

	result, err = client.TagByUserIDResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "mobileengagement.DevicesClient", "TagByUserID", resp, "Failure responding to request")
	}

	return
}

// TagByUserIDPreparer prepares the TagByUserID request.
func (client DevicesClient) TagByUserIDPreparer(parameters DeviceTagsParameters) (*http.Request, error) {
	pathParameters := map[string]interface{}{
		"appCollection":     autorest.Encode("path", client.AppCollection),
		"appName":           autorest.Encode("path", client.AppName),
		"resourceGroupName": autorest.Encode("path", client.ResourceGroupName),
		"subscriptionId":    autorest.Encode("path", client.SubscriptionID),
	}

	queryParameters := map[string]interface{}{
		"api-version": client.APIVersion,
	}

	preparer := autorest.CreatePreparer(
		autorest.AsJSON(),
		autorest.AsPost(),
		autorest.WithBaseURL(client.BaseURI),
		autorest.WithPathParameters("/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.MobileEngagement/appcollections/{appCollection}/apps/{appName}/users/tag", pathParameters),
		autorest.WithJSON(parameters),
		autorest.WithQueryParameters(queryParameters))
	return preparer.Prepare(&http.Request{})
}

// TagByUserIDSender sends the TagByUserID request. The method will close the
// http.Response Body if it receives an error.
func (client DevicesClient) TagByUserIDSender(req *http.Request) (*http.Response, error) {
	return autorest.SendWithSender(client, req)
}

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