/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 * Copyright 2020-present Open Networking Foundation

 * 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.
 */
 /*
 * NOTE: This file was generated, manual edits will be overwritten!
 *
 * Generated by 'goCodeGenerator.py':
 *              https://github.com/cboling/OMCI-parser/README.md
 */

package generated

import (
	"encoding/base64"
	"encoding/binary"
	"errors"
	"fmt"
	"github.com/deckarep/golang-set"
	"github.com/google/gopacket"
	"reflect"
	"sort"
	"strings"
)

// Attribute types
type AttributeType uint8

const (
	UnknownAttributeType         AttributeType = iota // Not known
	OctetsAttributeType                               // Series of zero or more octets
	StringAttributeType                               // Readable String
	UnsignedIntegerAttributeType                      // Integer (0..max)
	TableAttributeType                                // Table (of Octets)
	SignedIntegerAttributeType                        // Signed integer, often expressed as 2's complement
	PointerAttributeType                              // Managed Entity ID or pointer to a Managed instance
	BitFieldAttributeType                             // Bitfield
	EnumerationAttributeType                          // Fixed number of values (Unsigned Integers)
	CounterAttributeType                              // Incrementing counter
)

// AttributeDefinitionMap is a map of attribute definitions with the attribute index (0..15)
// as the key
type AttributeDefinitionMap map[uint]AttributeDefinition

// AttributeDefinition defines a single specific Managed Entity's attributes
type AttributeDefinition struct {
	Name          string
	AttributeType AttributeType
	Index         uint
	Mask          uint16
	DefValue      interface{}
	Size          int        // Size of attribute in bytes. 0 indicates variable/unknown
	Access        mapset.Set // AttributeAccess...
	Constraint    func(interface{}) *ParamError
	Avc           bool // If true, an AVC notification can occur for the attribute
	Tca           bool // If true, a threshold crossing alert alarm notification can occur for the attribute
	Optional      bool // If true, attribute is option, else mandatory
	Deprecated    bool // If true, attribute is deprecated
}

func (attr *AttributeDefinition) String() string {
	return fmt.Sprintf("AttributeDefinition: %v (%v/%v): Size: %v, Default: %v, Access: %v",
		attr.GetName(), attr.AttributeType, attr.GetIndex(), attr.GetSize(), attr.GetDefault(), attr.GetAccess())
}

// GetName returns the attribute's name
func (attr AttributeDefinition) GetName() string { return attr.Name }

// GetIndex returns the attribute index )0..15)
func (attr AttributeDefinition) GetIndex() uint { return attr.Index }

// GetDefault provides the default value for an attribute if not specified
// during its creation
func (attr AttributeDefinition) GetDefault() interface{} { return attr.DefValue }

// GetSize returns the size of the attribute. For table attributes, the size is
// the size of a single table.
func (attr AttributeDefinition) GetSize() int { return attr.Size }

// GetAccess provides the access information (Read, Write, ...)
func (attr AttributeDefinition) GetAccess() mapset.Set { return attr.Access }

// GetConstraints returns a function that can be called for the attribute
// that will validate the value. An appropriate error is returned if the
// constraint fails, otherwise nil is returned to indicate that the value
// is valid.
func (attr AttributeDefinition) GetConstraints() func(interface{}) *ParamError {
	return attr.Constraint
}

// IsTableAttribute returns true if the attribute is a table
func (attr AttributeDefinition) IsTableAttribute() bool {
	return attr.AttributeType == TableAttributeType
}

// IsCounter returns true if the attribute is a counter (usually expressed as an
// unsigned integer)
func (attr AttributeDefinition) IsCounter() bool {
	return attr.AttributeType == CounterAttributeType
}

// IsBitField returns true if the attribute is a bitfield
func (attr AttributeDefinition) IsBitField() bool {
	return attr.AttributeType == BitFieldAttributeType
}

// IsString returns true if the attribute is a string. Strings are typically encoded
// into fixed length files and padded with 0's
func (attr AttributeDefinition) IsString() bool {
	return attr.AttributeType == StringAttributeType
}

// Decode takes a slice of bytes and converts them into a value appropriate for
// the attribute, or returns an error on failure
func (attr *AttributeDefinition) Decode(data []byte, df gopacket.DecodeFeedback, msgType byte) (interface{}, error) {
	if attr.IsTableAttribute() {
		value, err := attr.tableAttributeDecode(data, df, msgType)
		if err != nil {
			return nil, err
		}
		if attr.GetConstraints() != nil {
			if omciErr := attr.GetConstraints()(value); omciErr != nil {
				return nil, omciErr.GetError()
			}
		}
		return value, nil
	}
	size := attr.GetSize()

	if len(data) < size {
		df.SetTruncated()
		return nil, NewMessageTruncatedError("packet too small for field")
	}
	switch attr.AttributeType {
	case StringAttributeType, OctetsAttributeType, UnknownAttributeType:
		value := make([]byte, size)
		copy(value, data[:size])
		if attr.GetConstraints() != nil {
			if omciErr := attr.GetConstraints()(value); omciErr != nil {
				return nil, omciErr.GetError()
			}
		}
		return value, nil

	default:
		switch attr.GetSize() {
		default:
			value := make([]byte, size)
			copy(value, data[:size])
			if attr.GetConstraints() != nil {
				if omciErr := attr.GetConstraints()(value); omciErr != nil {
					return nil, omciErr.GetError()
				}
			}
			return value, nil
		case 1:
			value := data[0]
			if attr.GetConstraints() != nil {
				if omciErr := attr.GetConstraints()(value); omciErr != nil {
					return nil, omciErr.GetError()
				}
			}
			return value, nil
		case 2:
			value := binary.BigEndian.Uint16(data[0:2])
			if attr.GetConstraints() != nil {
				if omciErr := attr.GetConstraints()(value); omciErr != nil {
					return nil, omciErr.GetError()
				}
			}
			return value, nil
		case 4:
			value := binary.BigEndian.Uint32(data[0:4])
			if attr.GetConstraints() != nil {
				if omciErr := attr.GetConstraints()(value); omciErr != nil {
					return nil, omciErr.GetError()
				}
			}
			return value, nil
		case 8:
			value := binary.BigEndian.Uint64(data[0:8])
			if attr.GetConstraints() != nil {
				omciErr := attr.GetConstraints()(value)
				if omciErr != nil {
					return nil, omciErr.GetError()
				}
			}
			return value, nil
		}
	}
}

// IOctetStream interface defines a way to convert a custom type to/from an octet
// stream.
type IOctetStream interface {
	ToOctetString() ([]byte, error)
	FromOctetString([]byte) (interface{}, error)
}

// InterfaceToOctets converts an attribute value to a string of octets
func InterfaceToOctets(input interface{}) ([]byte, error) {
	switch values := input.(type) {
	case []byte:
		return values, nil

	case []uint16:
		stream := make([]byte, 2*len(values))
		for index, value := range values {
			binary.BigEndian.PutUint16(stream[index*2:], value)
		}
		return stream, nil

	case []uint32:
		stream := make([]byte, 4*len(values))
		for index, value := range values {
			binary.BigEndian.PutUint32(stream[index*4:], value)
		}
		return stream, nil

	case []uint64:
		stream := make([]byte, 8*len(values))
		for index, value := range values {
			binary.BigEndian.PutUint64(stream[index*8:], value)
		}
		return stream, nil

	case IOctetStream:
		return values.ToOctetString()

	default:
		var typeName string
		if t := reflect.TypeOf(input); t.Kind() == reflect.Ptr {
			typeName = "*" + t.Elem().Name()
		} else {
			typeName = t.Name()
		}
		return nil, fmt.Errorf("unable to convert input to octet string: %v", typeName)
	}
}

// SerializeTo takes an attribute value and converts it to a slice of bytes ready
// for transmission
func (attr *AttributeDefinition) SerializeTo(value interface{}, b gopacket.SerializeBuffer,
	msgType byte, bytesAvailable int) (int, error) {
	if attr.IsTableAttribute() {
		return attr.tableAttributeSerializeTo(value, b, msgType, bytesAvailable)
	}
	if value == nil {
		return 0, fmt.Errorf("attribute: %v is nil", attr.Name)
	}
	size := attr.GetSize()
	if bytesAvailable < size {
		return 0, NewMessageTruncatedError(fmt.Sprintf("not enough space for attribute: %v", attr.Name))
	}
	bytes, err := b.AppendBytes(size)
	if err != nil {
		return 0, err
	}
	switch attr.AttributeType {
	case StringAttributeType, OctetsAttributeType, UnknownAttributeType:
		byteStream, err := InterfaceToOctets(value)
		if err != nil {
			return 0, err
		}
		copy(bytes, byteStream)

	default:
		switch size {
		default:
			byteStream, err := InterfaceToOctets(value)
			if err != nil {
				return 0, err
			}
			copy(bytes, byteStream)
		case 1:
			switch value.(type) {
			case int:
				bytes[0] = byte(value.(int))
			default:
				bytes[0] = value.(byte)
			}
		case 2:
			switch value.(type) {
			case int:
				binary.BigEndian.PutUint16(bytes, uint16(value.(int)))
			default:
				binary.BigEndian.PutUint16(bytes, value.(uint16))
			}
		case 4:
			switch value.(type) {
			case int:
				binary.BigEndian.PutUint32(bytes, uint32(value.(int)))
			default:
				binary.BigEndian.PutUint32(bytes, value.(uint32))
			}
		case 8:
			switch value.(type) {
			case int:
				binary.BigEndian.PutUint64(bytes, uint64(value.(int)))
			default:
				binary.BigEndian.PutUint64(bytes, value.(uint64))
			}
		}
	}
	return size, nil
}

// BufferToTableAttributes takes the reconstructed octet buffer transmitted for
// a table attribute (over many GetNextResponses) and converts it into the desired
// format for each table row
func (attr *AttributeDefinition) BufferToTableAttributes(data []byte) (interface{}, error) {
	// Source is network byte order octets. Convert to proper array of slices
	rowSize := attr.GetSize()
	dataSize := len(data)
	index := 0

	switch rowSize {
	default:
		value := make([][]byte, dataSize/rowSize)
		for offset := 0; offset < dataSize; offset += rowSize {
			value[index] = make([]byte, rowSize)
			copy(value[index], data[offset:])
			index++
		}
		return value, nil
	case 1:
		value := make([]byte, dataSize)
		copy(value, data)
		return value, nil
	case 2:
		value := make([]uint16, dataSize/2)
		for offset := 0; offset < dataSize; offset += rowSize {
			value[offset] = binary.BigEndian.Uint16(data[offset:])
			index++
		}
		return value, nil
	case 4:
		value := make([]uint32, dataSize/4)
		for offset := 0; offset < dataSize; offset += rowSize {
			value[offset] = binary.BigEndian.Uint32(data[offset:])
			index++
		}
		return value, nil
	case 8:
		value := make([]uint64, dataSize/8)
		for offset := 0; offset < dataSize; offset += rowSize {
			value[offset] = binary.BigEndian.Uint64(data[offset:])
			index++
		}
		return value, nil
	}
}

func (attr *AttributeDefinition) tableAttributeDecode(data []byte, df gopacket.DecodeFeedback, msgType byte) (interface{}, error) {
	// Serialization of a table depends on the type of message. A
	// Review of ITU-T G.988 shows that access on tables are
	// either Read and/or Write, never Set-by-Create
	switch msgType {
	default:
		return nil, fmt.Errorf("unsupported Message Type '%v' for table serialization", msgType)

	case byte(Get) | AK: // Get Response
		// Size
		value := binary.BigEndian.Uint32(data[0:4])
		return value, nil

	case byte(Set) | AR: // Set Request
		fallthrough

	case byte(GetNext) | AK: // Get Next Response
		// Block of data (octets) that need to be reassembled before conversion
		// to table/row-data.  If table attribute is not explicitly given a value
		// we have to assume the entire data buffer is the value. The receiver of
		// this frame will need to trim off any addtional information at the end
		// of the last frame sequence since they (and the ONU) are the only ones
		// who know how long the data really is.
		size := attr.GetSize()
		if size != 0 && len(data) < attr.GetSize() {
			df.SetTruncated()
			return nil, NewMessageTruncatedError("packet too small for field")
		} else if size == 0 {
			return nil, NewProcessingError("table attributes with no size are not supported: %v", attr.Name)
		}
		return data, nil

	case byte(SetTable) | AR: // Set Table Request
		// TODO: Only baseline supported at this time
		return nil, errors.New("attribute encode for set-table-request not yet supported")
	}
	return nil, errors.New("TODO")
}

func (attr *AttributeDefinition) tableAttributeSerializeTo(value interface{}, b gopacket.SerializeBuffer, msgType byte,
	bytesAvailable int) (int, error) {
	// Serialization of a table depends on the type of message. A
	// Review of ITU-T G.988 shows that access on tables are
	// either Read and/or Write, never Set-by-Create
	switch msgType {
	default:
		return 0, fmt.Errorf("unsupported Message Type '%v' for table serialization", msgType)

	case byte(Get) | AK: // Get Response
		// Size
		if bytesAvailable < 4 {
			return 0, NewMessageTruncatedError(fmt.Sprintf("not enough space for attribute: %v", attr.Name))
		}
		if dwordSize, ok := value.(uint32); ok {
			bytes, err := b.AppendBytes(4)
			if err != nil {
				return 0, err
			}
			binary.BigEndian.PutUint32(bytes, dwordSize)
			return 4, nil
		}
		return 0, errors.New("unexpected type for table serialization")

	case byte(GetNext) | AK: // Get Next Response
		// Values are already in network by order form
		if data, ok := value.([]byte); ok {
			if bytesAvailable < len(data) {
				return 0, NewMessageTruncatedError(fmt.Sprintf("not enough space for attribute: %v", attr.Name))
			}
			bytes, err := b.AppendBytes(len(data))
			if err != nil {
				return 0, err
			}
			copy(bytes, data)
			return len(data), nil
		}
		return 0, errors.New("unexpected type for table serialization")

	case byte(Set) | AR: // Set Request
		// TODO: For complex table types (such as extended vlan tagging config) create an
		//       interface definition. Provide a switch type to look for that as well as for
		//       value being a byte slice...  For now, just byte slice provided
		break

	case byte(SetTable) | AR: // Set Table Request
		// TODO: Only baseline supported at this time
		return 0, errors.New("attribute encode for set-table-request not yet supported")
	}
	size := attr.GetSize()
	if bytesAvailable < size {
		return 0, NewMessageTruncatedError(fmt.Sprintf("not enough space for attribute: %v", attr.Name))
	}
	bytes, err := b.AppendBytes(size)
	if err != nil {
		return 0, err
	}
	switch attr.GetSize() {
	default:
		copy(bytes, value.([]byte))
	case 1:
		switch value.(type) {
		case int:
			bytes[0] = byte(value.(int))
		default:
			bytes[0] = value.(byte)
		}
	case 2:
		switch value.(type) {
		case int:
			binary.BigEndian.PutUint16(bytes, uint16(value.(int)))
		default:
			binary.BigEndian.PutUint16(bytes, value.(uint16))
		}
	case 4:
		switch value.(type) {
		case int:
			binary.BigEndian.PutUint32(bytes, uint32(value.(int)))
		default:
			binary.BigEndian.PutUint32(bytes, value.(uint32))
		}
	case 8:
		switch value.(type) {
		case int:
			binary.BigEndian.PutUint64(bytes, uint64(value.(int)))
		default:
			binary.BigEndian.PutUint64(bytes, value.(uint64))
		}
	}
	return size, nil
}

// GetAttributeDefinitionByName searches the attribute definition map for the
// attribute with the specified name (case insensitive)
func GetAttributeDefinitionByName(attrMap AttributeDefinitionMap, name string) (*AttributeDefinition, error) {
	nameLower := strings.ToLower(name)
	for _, attrVal := range attrMap {
		if nameLower == strings.ToLower(attrVal.GetName()) {
			return &attrVal, nil
		}
	}
	return nil, errors.New(fmt.Sprintf("attribute '%s' not found", name))
}

// GetAttributeDefinitionMapKeys is a convenience functions since we may need to
// iterate a map in key index order. Maps in Go since v1.0 the iteration order
// of maps have been randomized.
func GetAttributeDefinitionMapKeys(attrMap AttributeDefinitionMap) []uint {
	var keys []uint
	for k := range attrMap {
		keys = append(keys, k)
	}
	sort.Slice(keys, func(i, j int) bool { return keys[i] < keys[j] })
	return keys
}

// GetAttributeBitmap returns the attribute bitmask for a single attribute
func GetAttributeBitmap(attrMap AttributeDefinitionMap, name string) (uint16, error) {
	attrDef, err := GetAttributeDefinitionByName(attrMap, name)
	if err != nil {
		return 0, err
	}
	index := attrDef.GetIndex()
	if index == 0 {
		return 0, errors.New("managed entity ID should not be used in an attribute bitmask")
	}
	return uint16(1 << (16 - index)), nil
}

// GetAttributesBitmap is a convenience functions to scan a list of attributes
// and return the bitmask that represents them
func GetAttributesBitmap(attrMap AttributeDefinitionMap, attributes mapset.Set) (uint16, error) {
	var mask uint16
	for _, def := range attrMap {
		if attributes.Contains(def.Name) {
			mask |= def.Mask
			attributes.Remove(def.Name)
		}
	}
	if attributes.Cardinality() > 0 {
		return 0, fmt.Errorf("unsupported attributes: %v", attributes)
	}
	return mask, nil
}

// GetAttributesValueMap returns the attribute value map with uninitialized values based
// on the attribute bitmask
func GetAttributesValueMap(attrDefs AttributeDefinitionMap, mask uint16, access mapset.Set) (AttributeValueMap, OmciErrors) {
	attrMap := make(AttributeValueMap, 0)
	for index, def := range attrDefs {
		if index == 0 {
			continue
		}
		checkMask := def.Mask
		accessOk := access == nil || def.GetAccess().Intersect(access).Cardinality() > 0

		if (mask&checkMask) != 0 && accessOk {
			attrMap[def.GetName()] = nil
			mask &= ^checkMask
		}
	}
	if mask != 0 {
		// Return map, but signaled failed attributes
		return attrMap, NewParameterError(mask)
	}
	return attrMap, NewOmciSuccess()
}

///////////////////////////////////////////////////////////////////////
// Packet definitions for attributes of various types/sizes
func toOctets(str string) []byte {
	data, err := base64.StdEncoding.DecodeString(str)
	if err != nil {
		panic(fmt.Sprintf("Invalid Base-64 string: '%v'", str))
	}
	return data
}

///////////////////////////////////////////////////////////////////////
// Packet definitions for attributes of various types/sizes

// ByteField returns an AttributeDefinition for an attribute that is encoded as a single
// octet (8-bits).
func ByteField(name string, attrType AttributeType, mask uint16, defVal uint8, access mapset.Set, avc bool,
	optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      defVal,
		Size:          1,
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// Uint16Field returns an AttributeDefinition for an attribute that is encoded as two
// octet (16-bits).
func Uint16Field(name string, attrType AttributeType, mask uint16, defVal uint16, access mapset.Set, avc bool,
	optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      defVal,
		Size:          2,
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// Uint32Field returns an AttributeDefinition for an attribute that is encoded as four
// octet (32-bits).
func Uint32Field(name string, attrType AttributeType, mask uint16, defVal uint32, access mapset.Set, avc bool,
	optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      defVal,
		Size:          4,
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// Uint64Field returns an AttributeDefinition for an attribute that is encoded as eight
// octet (64-bits).
func Uint64Field(name string, attrType AttributeType, mask uint16, defVal uint64, access mapset.Set, avc bool,
	optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      defVal,
		Size:          8,
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// MultiByteField returns an AttributeDefinition for an attribute that is encoded as multiple
// octets that do not map into fields with a length that is 1, 2, 4, or 8 octets.
func MultiByteField(name string, attrType AttributeType, mask uint16, size uint, defVal []byte, access mapset.Set, avc bool,
	optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      defVal,
		Size:          int(size),
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// Notes on various OMCI ME Table attribute fields.  This comment will eventually be
// removed once a good table solution is implemented.  These are not all the MEs with
// table attributes, but probably ones I care about to support initially.
//
//   ME                     Notes
//  --------------------------------------------------------------------------------------------
//	Port-mapping package -> Combined Port table -> N * 25 sized rows (port (1) + ME(2) * 12)
//  ONU Remote Debug     -> Reply table (N bytes)
//  ONU3-G               -> Status snapshot recordtable M x N bytes
//  MCAST Gem interworkTP-> IPv4 multicast adress table (12*n) (two 2 byte fields, two 4 byte fields)
//                          IPv6 multicast adress table (24*n) (various sub-fields)
//  L2 mcast gem TP      -> MCAST MAC addr filtering table (11 * n) (various sub-fields)
//  MAC Bridge Port Filt -> MAC Filter table (8 * n) (3 fields, some are bits)      *** BITS ***
//  MAC Bridge Port data -> Bridge Table (8*M) (vaius fields, some are bits)        *** BITS ***
//  VLAN tagging filter  -> Rx Vlan tag op table (16 * n) Lots of bit fields        *** BITS ***
//  MCAST operations profile
//  MCAST Subscriber config info
//  MCAST subscriber monitor
//  OMCI                -> Two tables (N bytes and 2*N bytes)
//  General pupose buffer   -> N bytes
//  Enhanced security control (17 * N bytes), (16 * P Bytes) , (16 * Q bytes), and more...
//
// An early example of info to track

// TableInfo is an early prototype of how to better model some tables that are
// difficult to code.
//
// The Value member may be one of the following:
//   nil    : Empty, no default, ...
//   value  : A specific value that equates to one row, ie) 6  or toOctets("base64")
//   array  : One or more rows of values.  [2]uint16{2, 3}
type TableInfo struct {
	Value interface{} // See comment above
	Size  int         // Table Row Size
}

func (t *TableInfo) String() string {
	return fmt.Sprintf("TableInfo: Size: %d, Value(s): %v", t.Size, t.Value)
}

// TableField is used to define an attribute that is a table
func TableField(name string, attrType AttributeType, mask uint16, tableInfo TableInfo, access mapset.Set,
	avc bool, optional bool, deprecated bool, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: attrType,
		Mask:          mask,
		Index:         index,
		DefValue:      tableInfo.Value,
		Size:          tableInfo.Size, //Number of elements
		Access:        access,
		Avc:           avc,
		Optional:      optional,
		Deprecated:    deprecated,
	}
}

// UnknownField is currently not used and may be deprecated. Its original intent
// was to be a placeholder during table attribute development
func UnknownField(name string, mask uint16, size int, index uint) AttributeDefinition {
	return AttributeDefinition{
		Name:          name,
		AttributeType: UnknownAttributeType, // Stored as octet string
		Mask:          mask,
		Index:         index,
		DefValue:      nil,
		Size:          size,
		Access:        mapset.NewSet(Read, Write),
		Avc:           false,
		Optional:      false,
		Deprecated:    false,
	}
}

// AttributeValueMap maps an attribute (by name) to its value
type AttributeValueMap map[string]interface{}

// MergeInDefaultValues will examine the Manage Entity defaults (for non-SetByCreate attributes). This
// function is called on a MIB Create request but is provide for external use in case it is needed
// before the MIB entry is created
func MergeInDefaultValues(classID ClassID, attributes AttributeValueMap) OmciErrors {
	// Get default values for non-SetByCreate attributes
	attrDefs, err := GetAttributesDefinitions(classID)
	if err.StatusCode() != Success {
		return err
	} else if attributes == nil {
		return NewProcessingError("Invalid (nil) Attribute Value Map referenced")
	}
	nilAllowed := mapset.NewSet(StringAttributeType, OctetsAttributeType, TableAttributeType)
	for index, attrDef := range attrDefs {
		if !attrDef.Access.Contains(SetByCreate) && index != 0 &&
			(attrDef.DefValue != nil || nilAllowed.Contains(attrDef.AttributeType)) {
			name := attrDef.GetName()
			if existing, found := attributes[name]; !found || existing == nil {
				attributes[name] = attrDef.DefValue
			}
		}
	}
	return err
}
