package aad

// 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"
	"github.com/Azure/go-autorest/autorest/date"
	"net/http"
)

// ExternalAccess enumerates the values for external access.
type ExternalAccess string

const (
	// Disabled ...
	Disabled ExternalAccess = "Disabled"
	// Enabled ...
	Enabled ExternalAccess = "Enabled"
)

// Ldaps enumerates the values for ldaps.
type Ldaps string

const (
	// LdapsDisabled ...
	LdapsDisabled Ldaps = "Disabled"
	// LdapsEnabled ...
	LdapsEnabled Ldaps = "Enabled"
)

// DomainService domain service.
type DomainService struct {
	autorest.Response `json:"-"`
	// DomainServiceProperties - Domain service properties
	*DomainServiceProperties `json:"properties,omitempty"`
	// ID - Resource Id
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
	// Etag - Resource etag
	Etag *string `json:"etag,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for DomainService struct.
func (ds *DomainService) 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 domainServiceProperties DomainServiceProperties
				err = json.Unmarshal(*v, &domainServiceProperties)
				if err != nil {
					return err
				}
				ds.DomainServiceProperties = &domainServiceProperties
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ds.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ds.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ds.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				ds.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				ds.Tags = tags
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				ds.Etag = &etag
			}
		}
	}

	return nil
}

// DomainServiceListResult the response from the List Domain Services operation.
type DomainServiceListResult struct {
	autorest.Response `json:"-"`
	// Value - the list of domain services.
	Value *[]DomainService `json:"value,omitempty"`
}

// DomainServicePatchProperties update Properties of the Domain Service.
type DomainServicePatchProperties struct {
	// LdapsSettings - Secure LDAP Settings
	LdapsSettings *LdapsSettings `json:"ldapsSettings,omitempty"`
}

// DomainServiceProperties properties of the Domain Service.
type DomainServiceProperties struct {
	// TenantID - Azure Active Directory tenant id
	TenantID *string `json:"tenantId,omitempty"`
	// DomainName - The name of the Azure domain that the user would like to deploy Domain Services to.
	DomainName *string `json:"domainName,omitempty"`
	// VnetSiteID - Virtual network site id
	VnetSiteID *string `json:"vnetSiteId,omitempty"`
	// SubnetID - The name of the virtual network that Domain Services will be deployed on. The id of the subnet that Domain Services will be deployed on. /virtualNetwork/vnetName/subnets/subnetName.
	SubnetID *string `json:"subnetId,omitempty"`
	// LdapsSettings - Secure LDAP Settings
	LdapsSettings *LdapsSettings `json:"ldapsSettings,omitempty"`
	// DomainControllerIPAddress - List of Domain Controller IP Address
	DomainControllerIPAddress *[]string `json:"domainControllerIpAddress,omitempty"`
	// ServiceStatus - Status of Domain Service instance
	ServiceStatus *string `json:"serviceStatus,omitempty"`
	// ProvisioningState - the current deployment or provisioning state, which only appears in the response.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// DomainServicesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type DomainServicesCreateOrUpdateFuture 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 DomainServicesCreateOrUpdateFuture) Result(client DomainServicesClient) (ds DomainService, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ds, azure.NewAsyncOpIncompleteError("aad.DomainServicesCreateOrUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ds, err = client.CreateOrUpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "aad.DomainServicesCreateOrUpdateFuture", "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, "aad.DomainServicesCreateOrUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	ds, err = client.CreateOrUpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesCreateOrUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// DomainServicesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type DomainServicesDeleteFuture 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 DomainServicesDeleteFuture) Result(client DomainServicesClient) (ds DomainService, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ds, azure.NewAsyncOpIncompleteError("aad.DomainServicesDeleteFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ds, err = client.DeleteResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "aad.DomainServicesDeleteFuture", "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, "aad.DomainServicesDeleteFuture", "Result", resp, "Failure sending request")
		return
	}
	ds, err = client.DeleteResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesDeleteFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// DomainServicesUpdateFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type DomainServicesUpdateFuture 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 DomainServicesUpdateFuture) Result(client DomainServicesClient) (ds DomainService, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		return ds, azure.NewAsyncOpIncompleteError("aad.DomainServicesUpdateFuture")
	}
	if future.PollingMethod() == azure.PollingLocation {
		ds, err = client.UpdateResponder(future.Response())
		if err != nil {
			err = autorest.NewErrorWithError(err, "aad.DomainServicesUpdateFuture", "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, "aad.DomainServicesUpdateFuture", "Result", resp, "Failure sending request")
		return
	}
	ds, err = client.UpdateResponder(resp)
	if err != nil {
		err = autorest.NewErrorWithError(err, "aad.DomainServicesUpdateFuture", "Result", resp, "Failure responding to request")
	}
	return
}

// LdapsSettings secure LDAP Settings
type LdapsSettings struct {
	// Ldaps - A flag to determine whether or not Secure LDAP is enabled or disabled. Possible values include: 'LdapsEnabled', 'LdapsDisabled'
	Ldaps Ldaps `json:"ldaps,omitempty"`
	// PfxCertificate - The certificate required to configure Secure LDAP. The parameter passed here should be a base64encoded representation of the certificate pfx file.
	PfxCertificate *string `json:"pfxCertificate,omitempty"`
	// PfxCertificatePassword - The password to decrypt the provided Secure LDAP certificate pfx file.
	PfxCertificatePassword *string `json:"pfxCertificatePassword,omitempty"`
	// PublicCertificate - Public certificate used to configure secure ldap.
	PublicCertificate *string `json:"publicCertificate,omitempty"`
	// CertificateThumbprint - Thumbprint of configure ldaps certificate.
	CertificateThumbprint *string `json:"certificateThumbprint,omitempty"`
	// CertificateNotAfter - NotAfter DateTime of configure ldaps certificate.
	CertificateNotAfter *date.Time `json:"certificateNotAfter,omitempty"`
	// ExternalAccess - A flag to determine whether or not Secure LDAP access over the internet is enabled or disabled. Possible values include: 'Enabled', 'Disabled'
	ExternalAccess ExternalAccess `json:"externalAccess,omitempty"`
	// ExternalAccessIPAddress - External access ip address.
	ExternalAccessIPAddress *string `json:"externalAccessIpAddress,omitempty"`
}

// OperationDisplayInfo the operation supported by Domain Services.
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: Domain Services.
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed.
	Resource *string `json:"resource,omitempty"`
}

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

// OperationEntityListResult the list of domain service operation response.
type OperationEntityListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of operations.
	Value *[]OperationEntity `json:"value,omitempty"`
}

// Resource the Resource model definition.
type Resource struct {
	// ID - Resource Id
	ID *string `json:"id,omitempty"`
	// Name - Resource name
	Name *string `json:"name,omitempty"`
	// Type - Resource type
	Type *string `json:"type,omitempty"`
	// Location - Resource location
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags
	Tags map[string]*string `json:"tags"`
	// Etag - Resource etag
	Etag *string `json:"etag,omitempty"`
}

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