// 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) Go Code Generator. DO NOT EDIT.

package ekm

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

// MarshalJSON implements the json.Marshaller interface for type Connection.
func (c Connection) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "host", c.Host)
	populate(objectMap, "path_prefix", c.PathPrefix)
	populateByteArray(objectMap, "server_ca_certificates", c.ServerCaCertificates, func() any {
		encodedValue := make([]string, len(c.ServerCaCertificates))
		for i := 0; i < len(c.ServerCaCertificates); i++ {
			encodedValue[i] = runtime.EncodeByteArray(c.ServerCaCertificates[i], runtime.Base64StdFormat)
		}
		return encodedValue
	})
	populate(objectMap, "server_subject_common_name", c.ServerSubjectCommonName)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type Connection.
func (c *Connection) 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 "host":
			err = unpopulate(val, "Host", &c.Host)
			delete(rawMsg, key)
		case "path_prefix":
			err = unpopulate(val, "PathPrefix", &c.PathPrefix)
			delete(rawMsg, key)
		case "server_ca_certificates":
			var encodedValue []string
			err = unpopulate(val, "ServerCaCertificates", &encodedValue)
			if err == nil && len(encodedValue) > 0 {
				c.ServerCaCertificates = make([][]byte, len(encodedValue))
				for i := 0; i < len(encodedValue) && err == nil; i++ {
					err = runtime.DecodeByteArray(encodedValue[i], &c.ServerCaCertificates[i], runtime.Base64StdFormat)
				}
			}
			delete(rawMsg, key)
		case "server_subject_common_name":
			err = unpopulate(val, "ServerSubjectCommonName", &c.ServerSubjectCommonName)
			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 ProxyClientCertificateInfo.
func (p ProxyClientCertificateInfo) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populateByteArray(objectMap, "ca_certificates", p.CaCertificates, func() any {
		encodedValue := make([]string, len(p.CaCertificates))
		for i := 0; i < len(p.CaCertificates); i++ {
			encodedValue[i] = runtime.EncodeByteArray(p.CaCertificates[i], runtime.Base64StdFormat)
		}
		return encodedValue
	})
	populate(objectMap, "subject_common_name", p.SubjectCommonName)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ProxyClientCertificateInfo.
func (p *ProxyClientCertificateInfo) 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", p, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "ca_certificates":
			var encodedValue []string
			err = unpopulate(val, "CaCertificates", &encodedValue)
			if err == nil && len(encodedValue) > 0 {
				p.CaCertificates = make([][]byte, len(encodedValue))
				for i := 0; i < len(encodedValue) && err == nil; i++ {
					err = runtime.DecodeByteArray(encodedValue[i], &p.CaCertificates[i], runtime.Base64StdFormat)
				}
			}
			delete(rawMsg, key)
		case "subject_common_name":
			err = unpopulate(val, "SubjectCommonName", &p.SubjectCommonName)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", p, err)
		}
	}
	return nil
}

// MarshalJSON implements the json.Marshaller interface for type ProxyInfo.
func (p ProxyInfo) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]any)
	populate(objectMap, "api_version", p.APIVersion)
	populate(objectMap, "ekm_product", p.EkmProduct)
	populate(objectMap, "ekm_vendor", p.EkmVendor)
	populate(objectMap, "proxy_name", p.ProxyName)
	populate(objectMap, "proxy_vendor", p.ProxyVendor)
	return json.Marshal(objectMap)
}

// UnmarshalJSON implements the json.Unmarshaller interface for type ProxyInfo.
func (p *ProxyInfo) 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", p, err)
	}
	for key, val := range rawMsg {
		var err error
		switch key {
		case "api_version":
			err = unpopulate(val, "APIVersion", &p.APIVersion)
			delete(rawMsg, key)
		case "ekm_product":
			err = unpopulate(val, "EkmProduct", &p.EkmProduct)
			delete(rawMsg, key)
		case "ekm_vendor":
			err = unpopulate(val, "EkmVendor", &p.EkmVendor)
			delete(rawMsg, key)
		case "proxy_name":
			err = unpopulate(val, "ProxyName", &p.ProxyName)
			delete(rawMsg, key)
		case "proxy_vendor":
			err = unpopulate(val, "ProxyVendor", &p.ProxyVendor)
			delete(rawMsg, key)
		}
		if err != nil {
			return fmt.Errorf("unmarshalling type %T: %v", p, 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 populateByteArray[T any](m map[string]any, k string, b []T, convert func() any) {
	if azcore.IsNullValue(b) {
		m[k] = nil
	} else if len(b) == 0 {
		return
	} else {
		m[k] = convert()
	}
}

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
}
