package eventgrid

// 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/azure"
	"net/http"
)

// EndpointType enumerates the values for endpoint type.
type EndpointType string

const (
	// EndpointTypeEventHub ...
	EndpointTypeEventHub EndpointType = "EventHub"
	// EndpointTypeEventSubscriptionDestination ...
	EndpointTypeEventSubscriptionDestination EndpointType = "EventSubscriptionDestination"
	// EndpointTypeWebHook ...
	EndpointTypeWebHook EndpointType = "WebHook"
)

// EventSubscriptionProvisioningState enumerates the values for event subscription provisioning state.
type EventSubscriptionProvisioningState string

const (
	// Canceled ...
	Canceled EventSubscriptionProvisioningState = "Canceled"
	// Creating ...
	Creating EventSubscriptionProvisioningState = "Creating"
	// Deleting ...
	Deleting EventSubscriptionProvisioningState = "Deleting"
	// Failed ...
	Failed EventSubscriptionProvisioningState = "Failed"
	// Succeeded ...
	Succeeded EventSubscriptionProvisioningState = "Succeeded"
	// Updating ...
	Updating EventSubscriptionProvisioningState = "Updating"
)

// ResourceRegionType enumerates the values for resource region type.
type ResourceRegionType string

const (
	// GlobalResource ...
	GlobalResource ResourceRegionType = "GlobalResource"
	// RegionalResource ...
	RegionalResource ResourceRegionType = "RegionalResource"
)

// TopicProvisioningState enumerates the values for topic provisioning state.
type TopicProvisioningState string

const (
	// TopicProvisioningStateCanceled ...
	TopicProvisioningStateCanceled TopicProvisioningState = "Canceled"
	// TopicProvisioningStateCreating ...
	TopicProvisioningStateCreating TopicProvisioningState = "Creating"
	// TopicProvisioningStateDeleting ...
	TopicProvisioningStateDeleting TopicProvisioningState = "Deleting"
	// TopicProvisioningStateFailed ...
	TopicProvisioningStateFailed TopicProvisioningState = "Failed"
	// TopicProvisioningStateSucceeded ...
	TopicProvisioningStateSucceeded TopicProvisioningState = "Succeeded"
	// TopicProvisioningStateUpdating ...
	TopicProvisioningStateUpdating TopicProvisioningState = "Updating"
)

// TopicTypeProvisioningState enumerates the values for topic type provisioning state.
type TopicTypeProvisioningState string

const (
	// TopicTypeProvisioningStateCanceled ...
	TopicTypeProvisioningStateCanceled TopicTypeProvisioningState = "Canceled"
	// TopicTypeProvisioningStateCreating ...
	TopicTypeProvisioningStateCreating TopicTypeProvisioningState = "Creating"
	// TopicTypeProvisioningStateDeleting ...
	TopicTypeProvisioningStateDeleting TopicTypeProvisioningState = "Deleting"
	// TopicTypeProvisioningStateFailed ...
	TopicTypeProvisioningStateFailed TopicTypeProvisioningState = "Failed"
	// TopicTypeProvisioningStateSucceeded ...
	TopicTypeProvisioningStateSucceeded TopicTypeProvisioningState = "Succeeded"
	// TopicTypeProvisioningStateUpdating ...
	TopicTypeProvisioningStateUpdating TopicTypeProvisioningState = "Updating"
)

// EventHubEventSubscriptionDestination information about the event hub destination for an event subscription
type EventHubEventSubscriptionDestination struct {
	// EventHubEventSubscriptionDestinationProperties - Event Hub Properties of the event subscription destination
	*EventHubEventSubscriptionDestinationProperties `json:"properties,omitempty"`
	// EndpointType - Possible values include: 'EndpointTypeEventSubscriptionDestination', 'EndpointTypeWebHook', 'EndpointTypeEventHub'
	EndpointType EndpointType `json:"endpointType,omitempty"`
}

// MarshalJSON is the custom marshaler for EventHubEventSubscriptionDestination.
func (ehesd EventHubEventSubscriptionDestination) MarshalJSON() ([]byte, error) {
	ehesd.EndpointType = EndpointTypeEventHub
	objectMap := make(map[string]interface{})
	if ehesd.EventHubEventSubscriptionDestinationProperties != nil {
		objectMap["properties"] = ehesd.EventHubEventSubscriptionDestinationProperties
	}
	objectMap["endpointType"] = ehesd.EndpointType
	return json.Marshal(objectMap)
}

// AsWebHookEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventHubEventSubscriptionDestination.
func (ehesd EventHubEventSubscriptionDestination) AsWebHookEventSubscriptionDestination() (*WebHookEventSubscriptionDestination, bool) {
	return nil, false
}

// AsEventHubEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventHubEventSubscriptionDestination.
func (ehesd EventHubEventSubscriptionDestination) AsEventHubEventSubscriptionDestination() (*EventHubEventSubscriptionDestination, bool) {
	return &ehesd, true
}

// AsEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventHubEventSubscriptionDestination.
func (ehesd EventHubEventSubscriptionDestination) AsEventSubscriptionDestination() (*EventSubscriptionDestination, bool) {
	return nil, false
}

// AsBasicEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventHubEventSubscriptionDestination.
func (ehesd EventHubEventSubscriptionDestination) AsBasicEventSubscriptionDestination() (BasicEventSubscriptionDestination, bool) {
	return &ehesd, true
}

// UnmarshalJSON is the custom unmarshaler for EventHubEventSubscriptionDestination struct.
func (ehesd *EventHubEventSubscriptionDestination) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var eventHubEventSubscriptionDestinationProperties EventHubEventSubscriptionDestinationProperties
				err = json.Unmarshal(*v, &eventHubEventSubscriptionDestinationProperties)
				if err != nil {
					return err
				}
				ehesd.EventHubEventSubscriptionDestinationProperties = &eventHubEventSubscriptionDestinationProperties
			}
		case "endpointType":
			if v != nil {
				var endpointType EndpointType
				err = json.Unmarshal(*v, &endpointType)
				if err != nil {
					return err
				}
				ehesd.EndpointType = endpointType
			}
		}
	}

	return nil
}

// EventHubEventSubscriptionDestinationProperties the properties for a event hub destination.
type EventHubEventSubscriptionDestinationProperties struct {
	// ResourceID - The Azure Resource Id that represents the endpoint of an Event Hub destination of an event subscription.
	ResourceID *string `json:"resourceId,omitempty"`
}

// EventSubscription event Subscription
type EventSubscription struct {
	autorest.Response `json:"-"`
	// EventSubscriptionProperties - Properties of the event subscription
	*EventSubscriptionProperties `json:"properties,omitempty"`
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for EventSubscription struct.
func (es *EventSubscription) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var eventSubscriptionProperties EventSubscriptionProperties
				err = json.Unmarshal(*v, &eventSubscriptionProperties)
				if err != nil {
					return err
				}
				es.EventSubscriptionProperties = &eventSubscriptionProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				es.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				es.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				es.Type = &typeVar
			}
		}
	}

	return nil
}

// BasicEventSubscriptionDestination information about the destination for an event subscription
type BasicEventSubscriptionDestination interface {
	AsWebHookEventSubscriptionDestination() (*WebHookEventSubscriptionDestination, bool)
	AsEventHubEventSubscriptionDestination() (*EventHubEventSubscriptionDestination, bool)
	AsEventSubscriptionDestination() (*EventSubscriptionDestination, bool)
}

// EventSubscriptionDestination information about the destination for an event subscription
type EventSubscriptionDestination struct {
	// EndpointType - Possible values include: 'EndpointTypeEventSubscriptionDestination', 'EndpointTypeWebHook', 'EndpointTypeEventHub'
	EndpointType EndpointType `json:"endpointType,omitempty"`
}

func unmarshalBasicEventSubscriptionDestination(body []byte) (BasicEventSubscriptionDestination, error) {
	var m map[string]interface{}
	err := json.Unmarshal(body, &m)
	if err != nil {
		return nil, err
	}

	switch m["endpointType"] {
	case string(EndpointTypeWebHook):
		var whesd WebHookEventSubscriptionDestination
		err := json.Unmarshal(body, &whesd)
		return whesd, err
	case string(EndpointTypeEventHub):
		var ehesd EventHubEventSubscriptionDestination
		err := json.Unmarshal(body, &ehesd)
		return ehesd, err
	default:
		var esd EventSubscriptionDestination
		err := json.Unmarshal(body, &esd)
		return esd, err
	}
}
func unmarshalBasicEventSubscriptionDestinationArray(body []byte) ([]BasicEventSubscriptionDestination, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	esdArray := make([]BasicEventSubscriptionDestination, len(rawMessages))

	for index, rawMessage := range rawMessages {
		esd, err := unmarshalBasicEventSubscriptionDestination(*rawMessage)
		if err != nil {
			return nil, err
		}
		esdArray[index] = esd
	}
	return esdArray, nil
}

// MarshalJSON is the custom marshaler for EventSubscriptionDestination.
func (esd EventSubscriptionDestination) MarshalJSON() ([]byte, error) {
	esd.EndpointType = EndpointTypeEventSubscriptionDestination
	objectMap := make(map[string]interface{})
	objectMap["endpointType"] = esd.EndpointType
	return json.Marshal(objectMap)
}

// AsWebHookEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventSubscriptionDestination.
func (esd EventSubscriptionDestination) AsWebHookEventSubscriptionDestination() (*WebHookEventSubscriptionDestination, bool) {
	return nil, false
}

// AsEventHubEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventSubscriptionDestination.
func (esd EventSubscriptionDestination) AsEventHubEventSubscriptionDestination() (*EventHubEventSubscriptionDestination, bool) {
	return nil, false
}

// AsEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventSubscriptionDestination.
func (esd EventSubscriptionDestination) AsEventSubscriptionDestination() (*EventSubscriptionDestination, bool) {
	return &esd, true
}

// AsBasicEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for EventSubscriptionDestination.
func (esd EventSubscriptionDestination) AsBasicEventSubscriptionDestination() (BasicEventSubscriptionDestination, bool) {
	return &esd, true
}

// EventSubscriptionFilter filter for the Event Subscription
type EventSubscriptionFilter struct {
	// SubjectBeginsWith - An optional string to filter events for an event subscription based on a resource path prefix.
	// The format of this depends on the publisher of the events.
	// Wildcard characters are not supported in this path.
	SubjectBeginsWith *string `json:"subjectBeginsWith,omitempty"`
	// SubjectEndsWith - An optional string to filter events for an event subscription based on a resource path suffix.
	// Wildcard characters are not supported in this path.
	SubjectEndsWith *string `json:"subjectEndsWith,omitempty"`
	// IncludedEventTypes - A list of applicable event types that need to be part of the event subscription.
	// If it is desired to subscribe to all event types, the string "all" needs to be specified as an element in this list.
	IncludedEventTypes *[]string `json:"includedEventTypes,omitempty"`
	// IsSubjectCaseSensitive - Specifies if the SubjectBeginsWith and SubjectEndsWith properties of the filter
	// should be compared in a case sensitive manner.
	IsSubjectCaseSensitive *bool `json:"isSubjectCaseSensitive,omitempty"`
}

// EventSubscriptionFullURL full endpoint url of an event subscription
type EventSubscriptionFullURL struct {
	autorest.Response `json:"-"`
	// EndpointURL - The URL that represents the endpoint of the destination of an event subscription.
	EndpointURL *string `json:"endpointUrl,omitempty"`
}

// EventSubscriptionProperties properties of the Event Subscription
type EventSubscriptionProperties struct {
	// Topic - Name of the topic of the event subscription.
	Topic *string `json:"topic,omitempty"`
	// ProvisioningState - Provisioning state of the event subscription. Possible values include: 'Creating', 'Updating', 'Deleting', 'Succeeded', 'Canceled', 'Failed'
	ProvisioningState EventSubscriptionProvisioningState `json:"provisioningState,omitempty"`
	// Destination - Information about the destination where events have to be delivered for the event subscription.
	Destination BasicEventSubscriptionDestination `json:"destination,omitempty"`
	// Filter - Information about the filter for the event subscription.
	Filter *EventSubscriptionFilter `json:"filter,omitempty"`
	// Labels - List of user defined labels.
	Labels *[]string `json:"labels,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for EventSubscriptionProperties struct.
func (esp *EventSubscriptionProperties) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "topic":
			if v != nil {
				var topic string
				err = json.Unmarshal(*v, &topic)
				if err != nil {
					return err
				}
				esp.Topic = &topic
			}
		case "provisioningState":
			if v != nil {
				var provisioningState EventSubscriptionProvisioningState
				err = json.Unmarshal(*v, &provisioningState)
				if err != nil {
					return err
				}
				esp.ProvisioningState = provisioningState
			}
		case "destination":
			if v != nil {
				destination, err := unmarshalBasicEventSubscriptionDestination(*v)
				if err != nil {
					return err
				}
				esp.Destination = destination
			}
		case "filter":
			if v != nil {
				var filter EventSubscriptionFilter
				err = json.Unmarshal(*v, &filter)
				if err != nil {
					return err
				}
				esp.Filter = &filter
			}
		case "labels":
			if v != nil {
				var labels []string
				err = json.Unmarshal(*v, &labels)
				if err != nil {
					return err
				}
				esp.Labels = &labels
			}
		}
	}

	return nil
}

// EventSubscriptionsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type EventSubscriptionsCreateOrUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future EventSubscriptionsCreateOrUpdateFuture) Result(client EventSubscriptionsClient) (es EventSubscription, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return es, azure.NewAsyncOpIncompleteError("eventgrid.EventSubscriptionsCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		es, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	es, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// EventSubscriptionsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type EventSubscriptionsDeleteFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future EventSubscriptionsDeleteFuture) Result(client EventSubscriptionsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ar, azure.NewAsyncOpIncompleteError("eventgrid.EventSubscriptionsDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ar, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsDeleteFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ar, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// EventSubscriptionsListResult result of the List EventSubscriptions operation
type EventSubscriptionsListResult struct {
	autorest.Response `json:"-"`
	// Value - A collection of EventSubscriptions
	Value *[]EventSubscription `json:"value,omitempty"`
}

// EventSubscriptionsUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type EventSubscriptionsUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future EventSubscriptionsUpdateFuture) Result(client EventSubscriptionsClient) (es EventSubscription, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return es, azure.NewAsyncOpIncompleteError("eventgrid.EventSubscriptionsUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		es, err = client.UpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	es, err = client.UpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.EventSubscriptionsUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// EventSubscriptionUpdateParameters properties of the Event Subscription update
type EventSubscriptionUpdateParameters struct {
	// Destination - Information about the destination where events have to be delivered for the event subscription.
	Destination BasicEventSubscriptionDestination `json:"destination,omitempty"`
	// Filter - Information about the filter for the event subscription.
	Filter *EventSubscriptionFilter `json:"filter,omitempty"`
	// Labels - List of user defined labels.
	Labels *[]string `json:"labels,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for EventSubscriptionUpdateParameters struct.
func (esup *EventSubscriptionUpdateParameters) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "destination":
			if v != nil {
				destination, err := unmarshalBasicEventSubscriptionDestination(*v)
				if err != nil {
					return err
				}
				esup.Destination = destination
			}
		case "filter":
			if v != nil {
				var filter EventSubscriptionFilter
				err = json.Unmarshal(*v, &filter)
				if err != nil {
					return err
				}
				esup.Filter = &filter
			}
		case "labels":
			if v != nil {
				var labels []string
				err = json.Unmarshal(*v, &labels)
				if err != nil {
					return err
				}
				esup.Labels = &labels
			}
		}
	}

	return nil
}

// EventType event Type for a subject under a topic
type EventType struct {
	// EventTypeProperties - Properties of the event type.
	*EventTypeProperties `json:"properties,omitempty"`
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for EventType struct.
func (et *EventType) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var eventTypeProperties EventTypeProperties
				err = json.Unmarshal(*v, &eventTypeProperties)
				if err != nil {
					return err
				}
				et.EventTypeProperties = &eventTypeProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				et.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				et.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				et.Type = &typeVar
			}
		}
	}

	return nil
}

// EventTypeProperties properties of the event type
type EventTypeProperties struct {
	// DisplayName - Display name of the event type.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - Description of the event type.
	Description *string `json:"description,omitempty"`
	// SchemaURL - Url of the schema for this event type.
	SchemaURL *string `json:"schemaUrl,omitempty"`
}

// EventTypesListResult result of the List Event Types operation
type EventTypesListResult struct {
	autorest.Response `json:"-"`
	// Value - A collection of event types
	Value *[]EventType `json:"value,omitempty"`
}

// Operation represents an operation returned by the GetOperations request
type Operation struct {
	// Name - Name of the operation
	Name *string `json:"name,omitempty"`
	// Display - Display name of the operation
	Display *OperationInfo `json:"display,omitempty"`
	// Origin - Origin of the operation
	Origin *string `json:"origin,omitempty"`
	// Properties - Properties of the operation
	Properties interface{} `json:"properties,omitempty"`
}

// OperationInfo information about an operation
type OperationInfo struct {
	// Provider - Name of the provider
	Provider *string `json:"provider,omitempty"`
	// Resource - Name of the resource type
	Resource *string `json:"resource,omitempty"`
	// Operation - Name of the operation
	Operation *string `json:"operation,omitempty"`
	// Description - Description of the operation
	Description *string `json:"description,omitempty"`
}

// OperationsListResult result of the List Operations operation
type OperationsListResult struct {
	autorest.Response `json:"-"`
	// Value - A collection of operations
	Value *[]Operation `json:"value,omitempty"`
}

// Resource definition of a Resource
type Resource struct {
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// Topic eventGrid Topic
type Topic struct {
	autorest.Response `json:"-"`
	// TopicProperties - Properties of the topic
	*TopicProperties `json:"properties,omitempty"`
	// Location - Location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - Tags of the resource
	Tags map[string]*string `json:"tags"`
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for Topic.
func (t Topic) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if t.TopicProperties != nil {
		objectMap["properties"] = t.TopicProperties
	}
	if t.Location != nil {
		objectMap["location"] = t.Location
	}
	if t.Tags != nil {
		objectMap["tags"] = t.Tags
	}
	if t.ID != nil {
		objectMap["id"] = t.ID
	}
	if t.Name != nil {
		objectMap["name"] = t.Name
	}
	if t.Type != nil {
		objectMap["type"] = t.Type
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Topic struct.
func (t *Topic) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var topicProperties TopicProperties
				err = json.Unmarshal(*v, &topicProperties)
				if err != nil {
					return err
				}
				t.TopicProperties = &topicProperties
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				t.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				t.Tags = tags
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				t.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				t.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				t.Type = &typeVar
			}
		}
	}

	return nil
}

// TopicProperties properties of the Topic
type TopicProperties struct {
	// ProvisioningState - Provisioning state of the topic. Possible values include: 'TopicProvisioningStateCreating', 'TopicProvisioningStateUpdating', 'TopicProvisioningStateDeleting', 'TopicProvisioningStateSucceeded', 'TopicProvisioningStateCanceled', 'TopicProvisioningStateFailed'
	ProvisioningState TopicProvisioningState `json:"provisioningState,omitempty"`
	// Endpoint - Endpoint for the topic.
	Endpoint *string `json:"endpoint,omitempty"`
}

// TopicRegenerateKeyRequest topic regenerate share access key key request
type TopicRegenerateKeyRequest struct {
	// KeyName - Key name to regenerate key1 or key2
	KeyName *string `json:"keyName,omitempty"`
}

// TopicsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type TopicsCreateOrUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future TopicsCreateOrUpdateFuture) Result(client TopicsClient) (t Topic, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return t, azure.NewAsyncOpIncompleteError("eventgrid.TopicsCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		t, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.TopicsCreateOrUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	t, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// TopicsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type TopicsDeleteFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future TopicsDeleteFuture) Result(client TopicsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ar, azure.NewAsyncOpIncompleteError("eventgrid.TopicsDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ar, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.TopicsDeleteFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ar, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// TopicSharedAccessKeys shared access keys of the Topic
type TopicSharedAccessKeys struct {
	autorest.Response `json:"-"`
	// Key1 - Shared access key1 for the topic.
	Key1 *string `json:"key1,omitempty"`
	// Key2 - Shared access key2 for the topic.
	Key2 *string `json:"key2,omitempty"`
}

// TopicsListResult result of the List Topics operation
type TopicsListResult struct {
	autorest.Response `json:"-"`
	// Value - A collection of Topics
	Value *[]Topic `json:"value,omitempty"`
}

// TopicsUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type TopicsUpdateFuture struct {
	azure.Future
	req *http.Request
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future TopicsUpdateFuture) Result(client TopicsClient) (t Topic, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return t, azure.NewAsyncOpIncompleteError("eventgrid.TopicsUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		t, err = client.UpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "eventgrid.TopicsUpdateFuture", "Result", future.Response(), "Failure responding to request")
		}
		return
	}
	var req *http.Request
	var resp *http.Response
	if future.PollingURL() != "" {
		req, err = http.NewRequest(http.MethodGet, future.PollingURL(), nil)
		if err != nil {
			return
		}
	} else {
		req = autorest.ChangeToGet(future.req)
	}
	resp, err = autorest.SendWithSender(client, req,
		autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	t, err = client.UpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "eventgrid.TopicsUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// TopicTypeInfo properties of a topic type info.
type TopicTypeInfo struct {
	autorest.Response `json:"-"`
	// TopicTypeProperties - Properties of the topic type info
	*TopicTypeProperties `json:"properties,omitempty"`
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// UnmarshalJSON is the custom unmarshaler for TopicTypeInfo struct.
func (tti *TopicTypeInfo) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var topicTypeProperties TopicTypeProperties
				err = json.Unmarshal(*v, &topicTypeProperties)
				if err != nil {
					return err
				}
				tti.TopicTypeProperties = &topicTypeProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				tti.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				tti.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				tti.Type = &typeVar
			}
		}
	}

	return nil
}

// TopicTypeProperties properties of a topic type.
type TopicTypeProperties struct {
	// Provider - Namespace of the provider of the topic type.
	Provider *string `json:"provider,omitempty"`
	// DisplayName - Display Name for the topic type.
	DisplayName *string `json:"displayName,omitempty"`
	// Description - Description of the topic type.
	Description *string `json:"description,omitempty"`
	// ResourceRegionType - Region type of the resource. Possible values include: 'RegionalResource', 'GlobalResource'
	ResourceRegionType ResourceRegionType `json:"resourceRegionType,omitempty"`
	// ProvisioningState - Provisioning state of the topic type. Possible values include: 'TopicTypeProvisioningStateCreating', 'TopicTypeProvisioningStateUpdating', 'TopicTypeProvisioningStateDeleting', 'TopicTypeProvisioningStateSucceeded', 'TopicTypeProvisioningStateCanceled', 'TopicTypeProvisioningStateFailed'
	ProvisioningState TopicTypeProvisioningState `json:"provisioningState,omitempty"`
	// SupportedLocations - List of locations supported by this topic type.
	SupportedLocations *[]string `json:"supportedLocations,omitempty"`
}

// TopicTypesListResult result of the List Topic Types operation
type TopicTypesListResult struct {
	autorest.Response `json:"-"`
	// Value - A collection of topic types
	Value *[]TopicTypeInfo `json:"value,omitempty"`
}

// TopicUpdateParameters properties of the Topic update
type TopicUpdateParameters struct {
	// Tags - Tags of the resource
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for TopicUpdateParameters.
func (tup TopicUpdateParameters) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if tup.Tags != nil {
		objectMap["tags"] = tup.Tags
	}
	return json.Marshal(objectMap)
}

// TrackedResource definition of a Tracked Resource
type TrackedResource struct {
	// Location - Location of the resource
	Location *string `json:"location,omitempty"`
	// Tags - Tags of the resource
	Tags map[string]*string `json:"tags"`
	// ID - Fully qualified identifier of the resource
	ID *string `json:"id,omitempty"`
	// Name - Name of the resource
	Name *string `json:"name,omitempty"`
	// Type - Type of the resource
	Type *string `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for TrackedResource.
func (tr TrackedResource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if tr.Location != nil {
		objectMap["location"] = tr.Location
	}
	if tr.Tags != nil {
		objectMap["tags"] = tr.Tags
	}
	if tr.ID != nil {
		objectMap["id"] = tr.ID
	}
	if tr.Name != nil {
		objectMap["name"] = tr.Name
	}
	if tr.Type != nil {
		objectMap["type"] = tr.Type
	}
	return json.Marshal(objectMap)
}

// WebHookEventSubscriptionDestination information about the webhook destination for an event subscription
type WebHookEventSubscriptionDestination struct {
	// WebHookEventSubscriptionDestinationProperties - WebHook Properties of the event subscription destination
	*WebHookEventSubscriptionDestinationProperties `json:"properties,omitempty"`
	// EndpointType - Possible values include: 'EndpointTypeEventSubscriptionDestination', 'EndpointTypeWebHook', 'EndpointTypeEventHub'
	EndpointType EndpointType `json:"endpointType,omitempty"`
}

// MarshalJSON is the custom marshaler for WebHookEventSubscriptionDestination.
func (whesd WebHookEventSubscriptionDestination) MarshalJSON() ([]byte, error) {
	whesd.EndpointType = EndpointTypeWebHook
	objectMap := make(map[string]interface{})
	if whesd.WebHookEventSubscriptionDestinationProperties != nil {
		objectMap["properties"] = whesd.WebHookEventSubscriptionDestinationProperties
	}
	objectMap["endpointType"] = whesd.EndpointType
	return json.Marshal(objectMap)
}

// AsWebHookEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for WebHookEventSubscriptionDestination.
func (whesd WebHookEventSubscriptionDestination) AsWebHookEventSubscriptionDestination() (*WebHookEventSubscriptionDestination, bool) {
	return &whesd, true
}

// AsEventHubEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for WebHookEventSubscriptionDestination.
func (whesd WebHookEventSubscriptionDestination) AsEventHubEventSubscriptionDestination() (*EventHubEventSubscriptionDestination, bool) {
	return nil, false
}

// AsEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for WebHookEventSubscriptionDestination.
func (whesd WebHookEventSubscriptionDestination) AsEventSubscriptionDestination() (*EventSubscriptionDestination, bool) {
	return nil, false
}

// AsBasicEventSubscriptionDestination is the BasicEventSubscriptionDestination implementation for WebHookEventSubscriptionDestination.
func (whesd WebHookEventSubscriptionDestination) AsBasicEventSubscriptionDestination() (BasicEventSubscriptionDestination, bool) {
	return &whesd, true
}

// UnmarshalJSON is the custom unmarshaler for WebHookEventSubscriptionDestination struct.
func (whesd *WebHookEventSubscriptionDestination) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				var webHookEventSubscriptionDestinationProperties WebHookEventSubscriptionDestinationProperties
				err = json.Unmarshal(*v, &webHookEventSubscriptionDestinationProperties)
				if err != nil {
					return err
				}
				whesd.WebHookEventSubscriptionDestinationProperties = &webHookEventSubscriptionDestinationProperties
			}
		case "endpointType":
			if v != nil {
				var endpointType EndpointType
				err = json.Unmarshal(*v, &endpointType)
				if err != nil {
					return err
				}
				whesd.EndpointType = endpointType
			}
		}
	}

	return nil
}

// WebHookEventSubscriptionDestinationProperties information about the webhook destination properties for an event
// subscription.
type WebHookEventSubscriptionDestinationProperties struct {
	// EndpointURL - The URL that represents the endpoint of the destination of an event subscription.
	EndpointURL *string `json:"endpointUrl,omitempty"`
	// EndpointBaseURL - The base URL that represents the endpoint of the destination of an event subscription.
	EndpointBaseURL *string `json:"endpointBaseUrl,omitempty"`
}
