// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// Code generated by Microsoft (R) AutoRest Code Generator. DO NOT EDIT.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

package armextensiontypes

import (
	"encoding/json"
	"fmt"
	"github.com/Azure/azure-sdk-for-go/sdk/azcore"
	"reflect"
)

// MarshalJSON implements the json.Marshaller interface for type ClusterScopeSettings.
func (c ClusterScopeSettings) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "id", c.ID)
	populate(objectMap, "name", c.Name)
	populate(objectMap, "properties", c.Properties)
	populate(objectMap, "type", c.Type)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ClusterScopeSettings.
func (c *ClusterScopeSettings) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", c, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "id":
			err = unpopulate(val, "ID", &c.ID)
			delete(rawMsg, key)
		case "name":
			err = unpopulate(val, "Name", &c.Name)
			delete(rawMsg, key)
		case "properties":
			err = unpopulate(val, "Properties", &c.Properties)
			delete(rawMsg, key)
		case "type":
			err = unpopulate(val, "Type", &c.Type)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", c, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ClusterScopeSettingsProperties.
func (c ClusterScopeSettingsProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "allowMultipleInstances", c.AllowMultipleInstances)
	populate(objectMap, "defaultReleaseNamespace", c.DefaultReleaseNamespace)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ClusterScopeSettingsProperties.
func (c *ClusterScopeSettingsProperties) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", c, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "allowMultipleInstances":
			err = unpopulate(val, "AllowMultipleInstances", &c.AllowMultipleInstances)
			delete(rawMsg, key)
		case "defaultReleaseNamespace":
			err = unpopulate(val, "DefaultReleaseNamespace", &c.DefaultReleaseNamespace)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", c, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionType.
func (e ExtensionType) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "id", e.ID)
	populate(objectMap, "name", e.Name)
	populate(objectMap, "properties", e.Properties)
	populate(objectMap, "type", e.Type)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionType.
func (e *ExtensionType) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "id":
			err = unpopulate(val, "ID", &e.ID)
			delete(rawMsg, key)
		case "name":
			err = unpopulate(val, "Name", &e.Name)
			delete(rawMsg, key)
		case "properties":
			err = unpopulate(val, "Properties", &e.Properties)
			delete(rawMsg, key)
		case "type":
			err = unpopulate(val, "Type", &e.Type)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeProperties.
func (e ExtensionTypeProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "description", e.Description)
	populate(objectMap, "isManagedIdentityRequired", e.IsManagedIdentityRequired)
	populate(objectMap, "isSystemExtension", e.IsSystemExtension)
	populate(objectMap, "planInfo", e.PlanInfo)
	populate(objectMap, "publisher", e.Publisher)
	populate(objectMap, "supportedClusterTypes", e.SupportedClusterTypes)
	populate(objectMap, "supportedScopes", e.SupportedScopes)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeProperties.
func (e *ExtensionTypeProperties) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "description":
			err = unpopulate(val, "Description", &e.Description)
			delete(rawMsg, key)
		case "isManagedIdentityRequired":
			err = unpopulate(val, "IsManagedIdentityRequired", &e.IsManagedIdentityRequired)
			delete(rawMsg, key)
		case "isSystemExtension":
			err = unpopulate(val, "IsSystemExtension", &e.IsSystemExtension)
			delete(rawMsg, key)
		case "planInfo":
			err = unpopulate(val, "PlanInfo", &e.PlanInfo)
			delete(rawMsg, key)
		case "publisher":
			err = unpopulate(val, "Publisher", &e.Publisher)
			delete(rawMsg, key)
		case "supportedClusterTypes":
			err = unpopulate(val, "SupportedClusterTypes", &e.SupportedClusterTypes)
			delete(rawMsg, key)
		case "supportedScopes":
			err = unpopulate(val, "SupportedScopes", &e.SupportedScopes)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypePropertiesPlanInfo.
func (e ExtensionTypePropertiesPlanInfo) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "offerId", e.OfferID)
	populate(objectMap, "planId", e.PlanID)
	populate(objectMap, "publisherId", e.PublisherID)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypePropertiesPlanInfo.
func (e *ExtensionTypePropertiesPlanInfo) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "offerId":
			err = unpopulate(val, "OfferID", &e.OfferID)
			delete(rawMsg, key)
		case "planId":
			err = unpopulate(val, "PlanID", &e.PlanID)
			delete(rawMsg, key)
		case "publisherId":
			err = unpopulate(val, "PublisherID", &e.PublisherID)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypePropertiesSupportedScopes.
func (e ExtensionTypePropertiesSupportedScopes) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "clusterScopeSettings", e.ClusterScopeSettings)
	populate(objectMap, "defaultScope", e.DefaultScope)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypePropertiesSupportedScopes.
func (e *ExtensionTypePropertiesSupportedScopes) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "clusterScopeSettings":
			err = unpopulate(val, "ClusterScopeSettings", &e.ClusterScopeSettings)
			delete(rawMsg, key)
		case "defaultScope":
			err = unpopulate(val, "DefaultScope", &e.DefaultScope)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeVersionForReleaseTrain.
func (e ExtensionTypeVersionForReleaseTrain) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "id", e.ID)
	populate(objectMap, "name", e.Name)
	populate(objectMap, "properties", e.Properties)
	populate(objectMap, "type", e.Type)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeVersionForReleaseTrain.
func (e *ExtensionTypeVersionForReleaseTrain) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "id":
			err = unpopulate(val, "ID", &e.ID)
			delete(rawMsg, key)
		case "name":
			err = unpopulate(val, "Name", &e.Name)
			delete(rawMsg, key)
		case "properties":
			err = unpopulate(val, "Properties", &e.Properties)
			delete(rawMsg, key)
		case "type":
			err = unpopulate(val, "Type", &e.Type)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeVersionForReleaseTrainProperties.
func (e ExtensionTypeVersionForReleaseTrainProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "supportedClusterTypes", e.SupportedClusterTypes)
	populate(objectMap, "unsupportedKubernetesVersions", e.UnsupportedKubernetesVersions)
	populate(objectMap, "version", e.Version)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeVersionForReleaseTrainProperties.
func (e *ExtensionTypeVersionForReleaseTrainProperties) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "supportedClusterTypes":
			err = unpopulate(val, "SupportedClusterTypes", &e.SupportedClusterTypes)
			delete(rawMsg, key)
		case "unsupportedKubernetesVersions":
			err = unpopulate(val, "UnsupportedKubernetesVersions", &e.UnsupportedKubernetesVersions)
			delete(rawMsg, key)
		case "version":
			err = unpopulate(val, "Version", &e.Version)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeVersionForReleaseTrainPropertiesUnsupportedKubernetesVersions.
func (e ExtensionTypeVersionForReleaseTrainPropertiesUnsupportedKubernetesVersions) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "appliances", e.Appliances)
	populate(objectMap, "connectedCluster", e.ConnectedCluster)
	populate(objectMap, "managedCluster", e.ManagedCluster)
	populate(objectMap, "provisionedCluster", e.ProvisionedCluster)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeVersionForReleaseTrainPropertiesUnsupportedKubernetesVersions.
func (e *ExtensionTypeVersionForReleaseTrainPropertiesUnsupportedKubernetesVersions) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "appliances":
			err = unpopulate(val, "Appliances", &e.Appliances)
			delete(rawMsg, key)
		case "connectedCluster":
			err = unpopulate(val, "ConnectedCluster", &e.ConnectedCluster)
			delete(rawMsg, key)
		case "managedCluster":
			err = unpopulate(val, "ManagedCluster", &e.ManagedCluster)
			delete(rawMsg, key)
		case "provisionedCluster":
			err = unpopulate(val, "ProvisionedCluster", &e.ProvisionedCluster)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeVersionUnsupportedKubernetesMatrixItem.
func (e ExtensionTypeVersionUnsupportedKubernetesMatrixItem) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "distributions", e.Distributions)
	populate(objectMap, "unsupportedVersions", e.UnsupportedVersions)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeVersionUnsupportedKubernetesMatrixItem.
func (e *ExtensionTypeVersionUnsupportedKubernetesMatrixItem) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "distributions":
			err = unpopulate(val, "Distributions", &e.Distributions)
			delete(rawMsg, key)
		case "unsupportedVersions":
			err = unpopulate(val, "UnsupportedVersions", &e.UnsupportedVersions)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ExtensionTypeVersionsList.
func (e ExtensionTypeVersionsList) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "nextLink", e.NextLink)
	populate(objectMap, "value", e.Value)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ExtensionTypeVersionsList.
func (e *ExtensionTypeVersionsList) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", e, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "nextLink":
			err = unpopulate(val, "NextLink", &e.NextLink)
			delete(rawMsg, key)
		case "value":
			err = unpopulate(val, "Value", &e.Value)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", e, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type List.
func (l List) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "nextLink", l.NextLink)
	populate(objectMap, "value", l.Value)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type List.
func (l *List) UnmarshalJSON(data []byte) error {
	var rawMsg map[string]json.RawMessage
	if err := json.Unmarshal(data, &rawMsg); err != nil {
		return fmt.Errorf("unmarshalling type %T: %v", l, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "nextLink":
			err = unpopulate(val, "NextLink", &l.NextLink)
			delete(rawMsg, key)
		case "value":
			err = unpopulate(val, "Value", &l.Value)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", l, err)
		}
	}
	return nil
}

func populate(m map[string]any, k string, v any) {
	if v == nil {
		return
	} else if azcore.IsNullValue(v) {
		m[k] = nil
	} else if !reflect.ValueOf(v).IsNil() {
		m[k] = v
	}
}

func unpopulate(data json.RawMessage, fn string, v any) error {
	if data == nil || string(data) == "null" {
		return nil
	}
	if err := json.Unmarshal(data, v); err != nil {
		return fmt.Errorf("struct field %s: %v", fn, err)
	}
	return nil
}
