package advisor

// 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 (
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/satori/go.uuid"
	"net/http"
)

// Category enumerates the values for category.
type Category string

const (
	// Cost ...
	Cost Category = "Cost"
	// HighAvailability ...
	HighAvailability Category = "HighAvailability"
	// Performance ...
	Performance Category = "Performance"
	// Security ...
	Security Category = "Security"
)

// Impact enumerates the values for impact.
type Impact string

const (
	// High ...
	High Impact = "High"
	// Low ...
	Low Impact = "Low"
	// Medium ...
	Medium Impact = "Medium"
)

// Risk enumerates the values for risk.
type Risk string

const (
	// Error ...
	Error Risk = "Error"
	// None ...
	None Risk = "None"
	// Warning ...
	Warning Risk = "Warning"
)

// ListSuppressionContract ...
type ListSuppressionContract struct {
	autorest.Response `json:"-"`
	Value             *[]SuppressionContract `json:"value,omitempty"`
}

// OperationDisplayInfo the operation supported by Advisor.
type OperationDisplayInfo struct {
	// Description - The description of the operation.
	Description *string `json:"description,omitempty"`
	// Operation - The action that users can perform, based on their permission level.
	Operation *string `json:"operation,omitempty"`
	// Provider - Service provider: Microsoft Advisor.
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed.
	Resource *string `json:"resource,omitempty"`
}

// OperationEntity the operation supported by Advisor.
type OperationEntity struct {
	// Name - Operation name: {provider}/{resource}/{operation}.
	Name *string `json:"name,omitempty"`
	// Display - The operation supported by Advisor.
	Display *OperationDisplayInfo `json:"display,omitempty"`
}

// OperationEntityListResult the list of Advisor operations.
type OperationEntityListResult struct {
	autorest.Response `json:"-"`
	// NextLink - The link used to get the next page of operations.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - The list of operations.
	Value *[]OperationEntity `json:"value,omitempty"`
}

// OperationEntityListResultIterator provides access to a complete listing of OperationEntity values.
type OperationEntityListResultIterator struct {
	i    int
	page OperationEntityListResultPage
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *OperationEntityListResultIterator) Next() error {
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err := iter.page.Next()
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter OperationEntityListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter OperationEntityListResultIterator) Response() OperationEntityListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter OperationEntityListResultIterator) Value() OperationEntity {
	if !iter.page.NotDone() {
		return OperationEntity{}
	}
	return iter.page.Values()[iter.i]
}

// IsEmpty returns true if the ListResult contains no values.
func (oelr OperationEntityListResult) IsEmpty() bool {
	return oelr.Value == nil || len(*oelr.Value) == 0
}

// operationEntityListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (oelr OperationEntityListResult) operationEntityListResultPreparer() (*http.Request, error) {
	if oelr.NextLink == nil || len(to.String(oelr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare(&http.Request{},
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(oelr.NextLink)))
}

// OperationEntityListResultPage contains a page of OperationEntity values.
type OperationEntityListResultPage struct {
	fn   func(OperationEntityListResult) (OperationEntityListResult, error)
	oelr OperationEntityListResult
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *OperationEntityListResultPage) Next() error {
	next, err := page.fn(page.oelr)
	if err != nil {
		return err
	}
	page.oelr = next
	return nil
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page OperationEntityListResultPage) NotDone() bool {
	return !page.oelr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page OperationEntityListResultPage) Response() OperationEntityListResult {
	return page.oelr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page OperationEntityListResultPage) Values() []OperationEntity {
	if page.oelr.IsEmpty() {
		return nil
	}
	return *page.oelr.Value
}

// RecommendationProperties the properties of the recommendation.
type RecommendationProperties struct {
	// Category - The category of the recommendation. Possible values include: 'HighAvailability', 'Security', 'Performance', 'Cost'
	Category Category `json:"category,omitempty"`
	// Impact - The business impact of the recommendation. Possible values include: 'High', 'Medium', 'Low'
	Impact Impact `json:"impact,omitempty"`
	// ImpactedField - The resource type identified by Advisor.
	ImpactedField *string `json:"impactedField,omitempty"`
	// ImpactedValue - The resource identified by Advisor.
	ImpactedValue *string `json:"impactedValue,omitempty"`
	// LastUpdated - The most recent time that Advisor checked the validity of the recommendation.
	LastUpdated *date.Time `json:"lastUpdated,omitempty"`
	// Metadata - The recommendation metadata.
	Metadata *map[string]*map[string]interface{} `json:"metadata,omitempty"`
	// RecommendationTypeID - The recommendation-type GUID.
	RecommendationTypeID *string `json:"recommendationTypeId,omitempty"`
	// Risk - The potential risk of not implementing the recommendation. Possible values include: 'Error', 'Warning', 'None'
	Risk Risk `json:"risk,omitempty"`
	// ShortDescription - A summary of the recommendation.
	ShortDescription *ShortDescription `json:"shortDescription,omitempty"`
}

// Resource an Azure resource.
type Resource struct {
	// ID - The resource ID.
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - The type of the resource.
	Type *string `json:"type,omitempty"`
	// Location - The location of the resource. This cannot be changed after the resource is created.
	Location *string `json:"location,omitempty"`
	// Tags - The tags of the resource.
	Tags *map[string]*string `json:"tags,omitempty"`
}

// ResourceRecommendationBase advisor Recommendation.
type ResourceRecommendationBase struct {
	autorest.Response `json:"-"`
	// ID - The fully qualified recommendation ID, for example /subscriptions/subscriptionId/resourceGroups/resourceGroup1/providers/Microsoft.ClassicCompute/virtualMachines/vm1/providers/Microsoft.Advisor/recommendations/recommendationGUID.
	ID *string `json:"id,omitempty"`
	// Name - The name of recommendation.
	Name *string `json:"name,omitempty"`
	// RecommendationProperties - The properties of the recommendation.
	*RecommendationProperties `json:"properties,omitempty"`
	// SuppressionIds - The list of snoozed and dismissed rules for the recommendation.
	SuppressionIds *[]uuid.UUID `json:"suppressionIds,omitempty"`
	// Type - The recommendation type: Microsoft.Advisor/recommendations.
	Type *string `json:"type,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for ResourceRecommendationBase struct.
func (rrb *ResourceRecommendationBase) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	var v *json.RawMessage

	v = m["id"]
	if v != nil {
		var ID string
		err = json.Unmarshal(*m["id"], &ID)
		if err != nil {
			return err
		}
		rrb.ID = &ID
	}

	v = m["name"]
	if v != nil {
		var name string
		err = json.Unmarshal(*m["name"], &name)
		if err != nil {
			return err
		}
		rrb.Name = &name
	}

	v = m["properties"]
	if v != nil {
		var properties RecommendationProperties
		err = json.Unmarshal(*m["properties"], &properties)
		if err != nil {
			return err
		}
		rrb.RecommendationProperties = &properties
	}

	v = m["suppressionIds"]
	if v != nil {
		var suppressionIds []uuid.UUID
		err = json.Unmarshal(*m["suppressionIds"], &suppressionIds)
		if err != nil {
			return err
		}
		rrb.SuppressionIds = &suppressionIds
	}

	v = m["type"]
	if v != nil {
		var typeVar string
		err = json.Unmarshal(*m["type"], &typeVar)
		if err != nil {
			return err
		}
		rrb.Type = &typeVar
	}

	return nil
}

// ResourceRecommendationBaseListResult the list of Advisor recommendations.
type ResourceRecommendationBaseListResult struct {
	autorest.Response `json:"-"`
	// NextLink - The link used to get the next page of recommendations.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - The list of recommendations.
	Value *[]ResourceRecommendationBase `json:"value,omitempty"`
}

// ResourceRecommendationBaseListResultIterator provides access to a complete listing of ResourceRecommendationBase
// values.
type ResourceRecommendationBaseListResultIterator struct {
	i    int
	page ResourceRecommendationBaseListResultPage
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *ResourceRecommendationBaseListResultIterator) Next() error {
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err := iter.page.Next()
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ResourceRecommendationBaseListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter ResourceRecommendationBaseListResultIterator) Response() ResourceRecommendationBaseListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter ResourceRecommendationBaseListResultIterator) Value() ResourceRecommendationBase {
	if !iter.page.NotDone() {
		return ResourceRecommendationBase{}
	}
	return iter.page.Values()[iter.i]
}

// IsEmpty returns true if the ListResult contains no values.
func (rrblr ResourceRecommendationBaseListResult) IsEmpty() bool {
	return rrblr.Value == nil || len(*rrblr.Value) == 0
}

// resourceRecommendationBaseListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rrblr ResourceRecommendationBaseListResult) resourceRecommendationBaseListResultPreparer() (*http.Request, error) {
	if rrblr.NextLink == nil || len(to.String(rrblr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare(&http.Request{},
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rrblr.NextLink)))
}

// ResourceRecommendationBaseListResultPage contains a page of ResourceRecommendationBase values.
type ResourceRecommendationBaseListResultPage struct {
	fn    func(ResourceRecommendationBaseListResult) (ResourceRecommendationBaseListResult, error)
	rrblr ResourceRecommendationBaseListResult
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *ResourceRecommendationBaseListResultPage) Next() error {
	next, err := page.fn(page.rrblr)
	if err != nil {
		return err
	}
	page.rrblr = next
	return nil
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page ResourceRecommendationBaseListResultPage) NotDone() bool {
	return !page.rrblr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page ResourceRecommendationBaseListResultPage) Response() ResourceRecommendationBaseListResult {
	return page.rrblr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page ResourceRecommendationBaseListResultPage) Values() []ResourceRecommendationBase {
	if page.rrblr.IsEmpty() {
		return nil
	}
	return *page.rrblr.Value
}

// ShortDescription a summary of the recommendation.
type ShortDescription struct {
	// Problem - The issue or opportunity identified by the recommendation.
	Problem *string `json:"problem,omitempty"`
	// Solution - The remediation action suggested by the recommendation.
	Solution *string `json:"solution,omitempty"`
}

// SuppressionContract the details of the snoozed or dismissed rule; for example, the duration, name, and GUID
// associated with the rule.
type SuppressionContract struct {
	autorest.Response `json:"-"`
	// ID - The resource ID.
	ID *string `json:"id,omitempty"`
	// Name - The name of the resource.
	Name *string `json:"name,omitempty"`
	// Type - The type of the resource.
	Type *string `json:"type,omitempty"`
	// Location - The location of the resource. This cannot be changed after the resource is created.
	Location *string `json:"location,omitempty"`
	// Tags - The tags of the resource.
	Tags *map[string]*string `json:"tags,omitempty"`
	// SuppressionID - The GUID of the suppression.
	SuppressionID *string `json:"suppressionId,omitempty"`
	// TTL - The duration for which the suppression is valid.
	TTL *string `json:"ttl,omitempty"`
}
