func AddAuthenticationDelegation(name string, controller string, proof string, revoked bool) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		obj, err := NewRegisterDelegationProof(name, controller, proof, revoked)
		if err != nil {
			return err
		}
		if builder.DelegateAuthentication == nil {
			builder.DelegateAuthentication = map[string]*RegisterDelegationProof{}
		}
		builder.DelegateAuthentication[name] = obj
		return nil
	}
}
AddAuthenticationDelegation returns a function which will add authentication delegation to the RegisterDocument
this function is idempotent, so if the same key (with the same name/ID) is added, it overwrites the previous one
package register
import (
	"time"
	"github.com/Iotic-Labs/iotics-identity-go/pkg/identity"
)
const defaultVersion = "0.0.1"
var supportedVersions = []string{"0.0.0", "0.0.1"}
type RegisterDocumentBuilder struct {
	ID                     string
	Purpose                string
	Proof                  string
	Revoked                bool
	Metadata               Metadata
	Creator                string
	SpecVersion            string
	UpdateTime             int64
	Controller             string
	PublicKeys             map[string]*RegisterPublicKey
	AuthenticationKeys     map[string]*RegisterPublicKey
	DelegateAuthentication map[string]*RegisterDelegationProof
	DelegateControl        map[string]*RegisterDelegationProof
}
func defaultUpdateTimeMillis() int64 {
	return time.Now().UnixNano() / 1000000
}
func specVersionExists(val string) bool {
	for _, v := range supportedVersions {
		if v == val {
			return true
		}
	}
	return false
}
type RegisterDocumentOpts func(builder *RegisterDocumentBuilder) error
func NewRegisterDocument(opts []RegisterDocumentOpts) (*RegisterDocument, []error) {
	builder := &RegisterDocumentBuilder{}
	var errs []error
	for _, o := range opts {
		err := o(builder)
		if err != nil {
			errs = append(errs, err)
		}
	}
	if len(errs) != 0 {
		return nil, errs
	}
	doc, err := builder.build()
	if err != nil {
		errs = append(errs, err)
	}
	errs = append(errs, doc.Validate()...)
	if len(errs) != 0 {
		return nil, errs
	}
	return doc, nil
}
func (b RegisterDocumentBuilder) build() (*RegisterDocument, error) {
	specVersion := defaultVersion
	if b.SpecVersion != "" {
		specVersion = b.SpecVersion
	}
	doc := &RegisterDocument{
		Context:                DocumentContext,
		ID:                     b.ID,
		IoticsSpecVersion:      specVersion,
		IoticsDIDType:          b.Purpose,
		Controller:             b.Controller,
		Creator:                b.Creator,
		UpdateTime:             defaultUpdateTimeMillis(),
		Proof:                  b.Proof,
		Revoked:                b.Revoked,
		AuthenticationKeys:     convertRegisterPublicKeyMapToSlice(b.AuthenticationKeys),
		PublicKeys:             convertRegisterPublicKeyMapToSlice(b.PublicKeys),
		DelegateAuthentication: convertRegisterDelegationProofMapToSlice(b.DelegateAuthentication),
		DelegateControl:        convertRegisterDelegationProofMapToSlice(b.DelegateControl),
		Metadata:               b.Metadata,
	}
	return doc, nil
}
func CloneRegisterPublicKey(obj map[string]*RegisterPublicKey) map[string]*RegisterPublicKey {
	publicKeys := map[string]*RegisterPublicKey{}
	for k, v := range obj {
		cloned, _ := v.Clone()
		publicKeys[k] = cloned
	}
	return publicKeys
}
func CloneRegisterDelegationProof(obj map[string]*RegisterDelegationProof) map[string]*RegisterDelegationProof {
	newMap := map[string]*RegisterDelegationProof{}
	for k, v := range obj {
		cloned, _ := v.Clone()
		newMap[k] = cloned
	}
	return newMap
}
func (b RegisterDocumentBuilder) Clone() *RegisterDocumentBuilder {
	clone := &RegisterDocumentBuilder{
		PublicKeys:             CloneRegisterPublicKey(b.PublicKeys),
		AuthenticationKeys:     CloneRegisterPublicKey(b.AuthenticationKeys),
		DelegateAuthentication: CloneRegisterDelegationProof(b.DelegateAuthentication),
		DelegateControl:        CloneRegisterDelegationProof(b.DelegateControl),
		Revoked:                b.Revoked,
	}
	return clone
}
func AddFromExistingDocument(doc *RegisterDocument) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		builder.ID = doc.ID
		builder.Purpose = doc.IoticsDIDType
		builder.Proof = doc.Proof
		builder.Revoked = doc.Revoked
		builder.Controller = doc.Controller
		builder.Creator = doc.Creator
		builder.SpecVersion = doc.IoticsSpecVersion
		builder.PublicKeys = convertReturnPublicKeySliceToMap(doc.PublicKeys)
		builder.AuthenticationKeys = convertReturnPublicKeySliceToMap(doc.AuthenticationKeys)
		builder.DelegateControl = convertReturnDelegationSliceToMap(doc.DelegateControl)
		builder.DelegateAuthentication = convertReturnDelegationSliceToMap(doc.DelegateAuthentication)
		builder.Metadata = Metadata{
			Label:   doc.Metadata.Label,
			Comment: doc.Metadata.Comment,
			URL:     doc.Metadata.URL,
		}
		return nil
	}
}
func AddRootParams(id string, purpose identity.DidType, proof string, revoked bool) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		builder.ID = id
		builder.Purpose = purpose.String()
		builder.Proof = proof
		builder.Revoked = revoked
		return nil
	}
}
func AddPublicKey(name string, publicKeyBase58 string, revoked bool) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		obj, err := NewRegisterPublicKey(name, PublicKeyType, publicKeyBase58, revoked)
		if err != nil {
			return err
		}
		if builder.PublicKeys == nil {
			builder.PublicKeys = map[string]*RegisterPublicKey{}
		}
		builder.PublicKeys[name] = obj
		return nil
	}
}
func AddPublicKeyObj(obj *RegisterPublicKey) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		if builder.PublicKeys == nil {
			builder.PublicKeys = map[string]*RegisterPublicKey{}
		}
		builder.PublicKeys[obj.ID] = obj
		return nil
	}
}
func AddAuthenticationKey(name string, publicKeyBase58 string, revoked bool) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		obj, err := NewRegisterPublicKey(name, AuthenticationKeyType, publicKeyBase58, revoked)
		if err != nil {
			return err
		}
		if builder.AuthenticationKeys == nil {
			builder.AuthenticationKeys = map[string]*RegisterPublicKey{}
		}
		builder.AuthenticationKeys[name] = obj
		return nil
	}
}
func AddAuthenticationKeyObj(obj *RegisterPublicKey) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		if builder.AuthenticationKeys == nil {
			builder.AuthenticationKeys = map[string]*RegisterPublicKey{}
		}
		builder.AuthenticationKeys[obj.ID] = obj
		return nil
	}
}
func AddControlDelegation(name string, controller string, proof string, revoked bool) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		obj, err := NewRegisterDelegationProof(name, controller, proof, revoked)
		if err != nil {
			return err
		}
		if builder.DelegateControl == nil {
			builder.DelegateControl = map[string]*RegisterDelegationProof{}
		}
		builder.DelegateControl[name] = obj
		return nil
	}
}
func AddControlDelegationObj(obj *RegisterDelegationProof) RegisterDocumentOpts {
	return func(builder *RegisterDocumentBuilder) error {
		if builder.DelegateControl == nil {
			builder.DelegateControl = map[string]*RegisterDelegationProof{}
		}
		builder.DelegateControl[obj.ID] = obj
		return nil
	}
}