/*
 * 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"
	"reflect"
	"sort"
	"strings"

	mapset "github.com/deckarep/golang-set"
	"github.com/google/gopacket"
)

// 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")
	}
}

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
}
