//go:build go1.18
// +build go1.18

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

package armmarketplace

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

// MarshalJSON implements the json.Marshaller interface for type AcknowledgeOfferNotificationDetails.
func (a AcknowledgeOfferNotificationDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "acknowledge", a.Acknowledge)
	populate(objectMap, "addPlans", a.AddPlans)
	populate(objectMap, "dismiss", a.Dismiss)
	populate(objectMap, "removeOffer", a.RemoveOffer)
	populate(objectMap, "removePlans", a.RemovePlans)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type AdminRequestApprovalProperties.
func (a AdminRequestApprovalProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "adminAction", a.AdminAction)
	populate(objectMap, "administrator", a.Administrator)
	populate(objectMap, "approvedPlans", a.ApprovedPlans)
	populate(objectMap, "collectionIds", a.CollectionIDs)
	populate(objectMap, "comment", a.Comment)
	populate(objectMap, "displayName", a.DisplayName)
	populate(objectMap, "offerId", a.OfferID)
	populate(objectMap, "plans", a.Plans)
	populate(objectMap, "publisherId", a.PublisherID)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type BulkCollectionsDetails.
func (b BulkCollectionsDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "action", b.Action)
	populate(objectMap, "collectionIds", b.CollectionIDs)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type CollectionProperties.
func (c CollectionProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "allSubscriptions", c.AllSubscriptions)
	populate(objectMap, "claim", c.Claim)
	populate(objectMap, "collectionId", c.CollectionID)
	populate(objectMap, "collectionName", c.CollectionName)
	populate(objectMap, "enabled", c.Enabled)
	populate(objectMap, "numberOfOffers", c.NumberOfOffers)
	populate(objectMap, "subscriptionsList", c.SubscriptionsList)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type CollectionsToSubscriptionsMappingProperties.
func (c CollectionsToSubscriptionsMappingProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "subscriptionIds", c.SubscriptionIDs)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type NotificationsSettingsProperties.
func (n NotificationsSettingsProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "recipients", n.Recipients)
	populate(objectMap, "sendToAllMarketplaceAdmins", n.SendToAllMarketplaceAdmins)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type OfferProperties.
func (o OfferProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "createdAt", o.CreatedAt)
	populate(objectMap, "eTag", o.ETag)
	populate(objectMap, "iconFileUris", o.IconFileUris)
	populate(objectMap, "modifiedAt", o.ModifiedAt)
	populate(objectMap, "offerDisplayName", o.OfferDisplayName)
	populate(objectMap, "plans", o.Plans)
	populate(objectMap, "privateStoreId", o.PrivateStoreID)
	populate(objectMap, "publisherDisplayName", o.PublisherDisplayName)
	populate(objectMap, "specificPlanIdsLimitation", o.SpecificPlanIDsLimitation)
	populate(objectMap, "uniqueOfferId", o.UniqueOfferID)
	populate(objectMap, "updateSuppressedDueIdempotence", o.UpdateSuppressedDueIdempotence)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type PlanRequesterDetails.
func (p PlanRequesterDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "planDisplayName", p.PlanDisplayName)
	populate(objectMap, "planId", p.PlanID)
	populate(objectMap, "requesters", p.Requesters)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type PrivateStoreProperties.
func (p PrivateStoreProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "availability", p.Availability)
	populate(objectMap, "branding", p.Branding)
	populate(objectMap, "collectionIds", p.CollectionIDs)
	populate(objectMap, "eTag", p.ETag)
	populate(objectMap, "isGov", p.IsGov)
	populate(objectMap, "notificationsSettings", p.NotificationsSettings)
	populate(objectMap, "privateStoreId", p.PrivateStoreID)
	populate(objectMap, "privateStoreName", p.PrivateStoreName)
	populate(objectMap, "tenantId", p.TenantID)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type QueryApprovedPlans.
func (q QueryApprovedPlans) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "offerId", q.OfferID)
	populate(objectMap, "planIds", q.PlanIDs)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type RequestApprovalProperties.
func (r RequestApprovalProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "isClosed", r.IsClosed)
	populate(objectMap, "messageCode", r.MessageCode)
	populate(objectMap, "offerDisplayName", r.OfferDisplayName)
	populate(objectMap, "offerId", r.OfferID)
	populate(objectMap, "plansDetails", r.PlansDetails)
	populate(objectMap, "publisherId", r.PublisherID)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type RequestDetails.
func (r RequestDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "planIds", r.PlanIDs)
	populate(objectMap, "publisherId", r.PublisherID)
	populate(objectMap, "subscriptionId", r.SubscriptionID)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type StopSellSubscriptions.
func (s StopSellSubscriptions) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "subscriptions", s.Subscriptions)
	return json.Marshal(objectMap)
}

// MarshalJSON implements the json.Marshaller interface for type SystemData.
func (s SystemData) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populateTimeRFC3339(objectMap, "createdAt", s.CreatedAt)
	populate(objectMap, "createdBy", s.CreatedBy)
	populate(objectMap, "createdByType", s.CreatedByType)
	populateTimeRFC3339(objectMap, "lastModifiedAt", s.LastModifiedAt)
	populate(objectMap, "lastModifiedBy", s.LastModifiedBy)
	populate(objectMap, "lastModifiedByType", s.LastModifiedByType)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type SystemData.
func (s *SystemData) 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", s, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "createdAt":
			err = unpopulateTimeRFC3339(val, "CreatedAt", &s.CreatedAt)
			delete(rawMsg, key)
		case "createdBy":
			err = unpopulate(val, "CreatedBy", &s.CreatedBy)
			delete(rawMsg, key)
		case "createdByType":
			err = unpopulate(val, "CreatedByType", &s.CreatedByType)
			delete(rawMsg, key)
		case "lastModifiedAt":
			err = unpopulateTimeRFC3339(val, "LastModifiedAt", &s.LastModifiedAt)
			delete(rawMsg, key)
		case "lastModifiedBy":
			err = unpopulate(val, "LastModifiedBy", &s.LastModifiedBy)
			delete(rawMsg, key)
		case "lastModifiedByType":
			err = unpopulate(val, "LastModifiedByType", &s.LastModifiedByType)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", s, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type TransferOffersDetails.
func (t TransferOffersDetails) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	populate(objectMap, "offerIdsList", t.OfferIDsList)
	populate(objectMap, "operation", t.Operation)
	populate(objectMap, "targetCollections", t.TargetCollections)
	return json.Marshal(objectMap)
}

func populate(m map[string]interface{}, k string, v interface{}) {
	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 interface{}) error {
	if data == nil {
		return nil
	}
	if err := json.Unmarshal(data, v); err != nil {
		return fmt.Errorf("struct field %s: %v", fn, err)
	}
	return nil
}
