/*
 * 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/binary"
	"errors"
	"fmt"
	"github.com/deckarep/golang-set"
	"github.com/google/gopacket"
)

// ManagedEntity provides a complete instance of a Managed Entity
type ManagedEntity struct {
	definition             ManagedEntityDefinition
	attributeMask          uint16
	requestedAttributeMask uint16
	attributes             AttributeValueMap
}

// String provides a simple string that describes this struct
func (entity *ManagedEntity) String() string {
	return fmt.Sprintf("ManagedEntity: %v, EntityID: (%d/%#x): Attributes: %v",
		entity.GetClassID(), entity.GetEntityID(), entity.GetEntityID(), entity.attributes)
}

// NewManagedEntity creates a ManagedEntity given an ME Definition and parameter/attribute data
func NewManagedEntity(definition ManagedEntityDefinition, params ...ParamData) (*ManagedEntity, OmciErrors) {
	entity := &ManagedEntity{
		definition: definition,
		attributes: make(map[string]interface{}),
	}
	if params != nil {
		if err := entity.setAttributes(params...); err.StatusCode() != Success {
			return nil, err
		}
	}
	return entity, NewOmciSuccess()
}

// GetManagedEntityDefinition provides the ME definition of a Managed Entity
func (entity *ManagedEntity) GetManagedEntityDefinition() ManagedEntityDefinition {
	return entity.definition
}

// GetName provides the ME Name of a Managed Entity
func (entity ManagedEntity) GetName() string {
	return entity.definition.GetName()
}

// GetClassID returns the 16-bit class ID of a Managed Entity
func (entity ManagedEntity) GetClassID() ClassID {
	return entity.definition.GetClassID()
}

// SetClassID assigns the 16-bit class ID of a Managed Entity
func (entity *ManagedEntity) SetClassID(classID ClassID) {
	entity.definition.SetClassID(classID)
}

// GetMessageTypes returns the OMCI message types that a Managed Entity supports
func (entity ManagedEntity) GetMessageTypes() mapset.Set {
	return entity.definition.GetMessageTypes()
}

// GetAllowedAttributeMask returns the 16-bit bitmask of attributes a Managed Entity supports
func (entity ManagedEntity) GetAllowedAttributeMask() uint16 {
	return entity.definition.GetAllowedAttributeMask()
}

// GetAttributeDefinitions returns the attribute definition map for a Managed Entity
func (entity ManagedEntity) GetAttributeDefinitions() AttributeDefinitionMap {
	return entity.definition.GetAttributeDefinitions()
}

// DecodeAttributes will decode the attributes portion of a Managed Entity frame/packet
func (entity *ManagedEntity) DecodeAttributes(mask uint16, data []byte, p gopacket.PacketBuilder, msgType byte) (AttributeValueMap, error) {
	return entity.definition.DecodeAttributes(mask, data, p, msgType)
}

// SerializeAttributes will serialize the attributes of a Managed Entity type
func (entity *ManagedEntity) SerializeAttributes(attr AttributeValueMap, mask uint16,
	b gopacket.SerializeBuffer, msgType byte, bytesAvailable int, packData bool) (error, uint16) {
	return entity.definition.SerializeAttributes(attr, mask, b, msgType, bytesAvailable, packData)
}

// GetEntityID will return the Entity/Instance ID for a Managed Entity
func (entity *ManagedEntity) GetEntityID() uint16 {
	if eid, err := entity.GetAttributeByIndex(0); err == nil {
		return eid.(uint16)
	}
	return 0
}

// SetEntityID will set the Entity/Instance ID for a Managed Entity
func (entity *ManagedEntity) SetEntityID(eid uint16) error {
	return entity.SetAttributeByIndex(0, eid)
}

// GetAttributeMask will return the 16-bit attribute mask of a Managed Entity
func (entity *ManagedEntity) GetAttributeMask() uint16 {
	return entity.attributeMask
}

// SetRequestedAttributeMask is used to initialize the requested attribute mask to a specific
// value. This should only be done on "Get" type operations that need to fetch and attribute
// and store it in the entity. For other operations (create, set, ...) you should specify
// the attributes and values in the Params initialization or use the SetAttribute
func (entity *ManagedEntity) SetRequestedAttributeMask(mask uint16) {
	entity.requestedAttributeMask = mask
}

// GetRequestedAttributeMask will return the 16-bit requested attribute mask of a Managed Entity.
// This is only specified for requests that perform a Get operation
func (entity *ManagedEntity) GetRequestedAttributeMask() uint16 {
	return entity.requestedAttributeMask
}

// GetAttributeValueMap will return the map of attributes of a Managed Entity
func (entity *ManagedEntity) GetAttributeValueMap() AttributeValueMap {
	return entity.attributes
}

// GetAttribute will return the value of a specific attribute for the specified attribute by name
func (entity *ManagedEntity) GetAttribute(name string) (interface{}, error) {
	value, ok := entity.attributes[name]
	if !ok {
		return 0, fmt.Errorf("attribute '%v' not found", name)
	}
	return value, nil
}

// GetAttributeByIndex will return the value of a specific attribute for the specified attribute by index
func (entity *ManagedEntity) GetAttributeByIndex(index uint) (interface{}, error) {
	if len(entity.attributes) == 0 {
		return nil, errors.New("attributes have already been set")
	}
	if _, ok := entity.definition.AttributeDefinitions[index]; !ok {
		return nil, fmt.Errorf("invalid attribute index: %d, should be 0..%d",
			index, len(entity.definition.AttributeDefinitions)-1)
	}
	return entity.GetAttribute(entity.definition.AttributeDefinitions[index].Name)
}

func (entity *ManagedEntity) setAttributes(params ...ParamData) OmciErrors {
	if entity.attributes == nil {
		entity.attributes = make(map[string]interface{})
	} else if len(entity.attributes) > 0 {
		return NewNonStatusError("attributes have already been set")
	}
	eidName := entity.definition.AttributeDefinitions[0].Name
	if len(params) == 0 {
		entity.attributes[eidName] = uint16(0)
		return NewOmciSuccess()
	}
	entity.attributes[eidName] = params[0].EntityID

	for name, value := range params[0].Attributes {
		if name == eidName {
			continue
		}
		if err := entity.SetAttribute(name, value); err.StatusCode() != Success {
			return err
		}
	}
	return NewOmciSuccess()
}

// SetAttribute can be uses to set the value of a specific attribute by name
func (entity *ManagedEntity) SetAttribute(name string, value interface{}) OmciErrors {
	attrDef, err := GetAttributeDefinitionByName(entity.definition.GetAttributeDefinitions(), name)
	if err != nil {
		// Not found, which means not in the attribute definition map
		return NewProcessingError(err.Error())
	} else if entity.attributes == nil {
		entity.attributes = make(map[string]interface{})
	}
	mask := attrDef.Mask
	// check any constraints
	if constraintCheck := attrDef.GetConstraints(); constraintCheck != nil {
		err = constraintCheck(value)
		if err != nil {
			return NewParameterError(mask, entity.GetAttributeDefinitions(), err)
		}
	}
	entity.attributes[name] = value
	entity.attributeMask |= mask
	return NewOmciSuccess()
}

// SetAttributeByIndex can be uses to set the value of a specific attribute by attribute index (0..15)
func (entity *ManagedEntity) SetAttributeByIndex(index uint, value interface{}) error {
	attrDef, ok := entity.definition.AttributeDefinitions[index]
	if !ok {
		return fmt.Errorf("invalid attribute index: %d, should be 0..%d",
			index, len(entity.definition.AttributeDefinitions)-1)
	} else if entity.attributes == nil {
		entity.attributes = make(map[string]interface{})
	}
	mask := attrDef.Mask
	// check any constraints
	if constraintCheck := attrDef.GetConstraints(); constraintCheck != nil {
		err := constraintCheck(value)
		if err != nil {
			return NewParameterError(mask, entity.GetAttributeDefinitions(), err)
		}
	}
	entity.attributes[attrDef.Name] = value
	entity.attributeMask |= mask
	return nil
}

// DeleteAttribute is used to remove a specific attribute from a Managed Index by name
func (entity *ManagedEntity) DeleteAttribute(name string) error {
	attrDef, err := GetAttributeDefinitionByName(entity.definition.GetAttributeDefinitions(), name)
	if err != nil {
		return err
	}
	if entity.attributes != nil {
		delete(entity.attributes, name)
		entity.attributeMask &= ^attrDef.Mask
	}
	return nil
}

// DeleteAttributeByIndex is used to remove a specific attribute from a Managed Index by attribute index (0..15)
func (entity *ManagedEntity) DeleteAttributeByIndex(index uint) error {
	attrDef, ok := entity.definition.AttributeDefinitions[index]
	if !ok {
		return fmt.Errorf("invalid attribute index: %d, should be 0..%d",
			index, len(entity.definition.AttributeDefinitions)-1)
	}
	if entity.attributes != nil {
		delete(entity.attributes, attrDef.Name)
		entity.attributeMask &= ^attrDef.Mask
	}
	return nil
}

// GetClassSupport returns the ONU support for this managed entity
func (entity *ManagedEntity) GetClassSupport() ClassSupport {
	return entity.definition.GetClassSupport()
}

// GetAlarmMap returns the Alarm Bit Number to Alarm Name (string) mapping.  Nil is returned if
// the managed entity does not support alarms
func (entity *ManagedEntity) GetAlarmMap() AlarmMap {
	return entity.definition.GetAlarmMap()
}

// DecodeFromBytes decodes a Managed Entity give an octet stream pointing to the ME within a frame
func (entity *ManagedEntity) DecodeFromBytes(data []byte, p gopacket.PacketBuilder, msgType byte) error {
	if len(data) < 6 {
		p.SetTruncated()
		return errors.New("frame too small")
	}
	classID := ClassID(binary.BigEndian.Uint16(data[0:2]))
	entityID := binary.BigEndian.Uint16(data[2:4])
	parameters := ParamData{EntityID: entityID}

	meDefinition, omciErr := LoadManagedEntityDefinition(classID, parameters)
	if omciErr.StatusCode() != Success {
		return omciErr.GetError()
	}
	entity.definition = meDefinition.definition
	entity.attributeMask = binary.BigEndian.Uint16(data[4:6])
	entity.attributes = make(map[string]interface{})
	entity.SetEntityID(entityID)
	packetAttributes, err := entity.DecodeAttributes(entity.GetAttributeMask(), data[6:], p, msgType)
	if err != nil {
		return err
	}
	for name, value := range packetAttributes {
		entity.attributes[name] = value
	}
	return nil
}

// SerializeTo serializes a Managed Entity into an octet stream
func (entity *ManagedEntity) SerializeTo(b gopacket.SerializeBuffer, msgType byte, bytesAvailable int, opts gopacket.SerializeOptions) error {
	// Add class ID and entity ID
	bytes, err := b.AppendBytes(6)
	if err != nil {
		return err
	}
	binary.BigEndian.PutUint16(bytes, uint16(entity.GetClassID()))
	binary.BigEndian.PutUint16(bytes[2:], entity.GetEntityID())
	binary.BigEndian.PutUint16(bytes[4:], entity.GetAttributeMask())

	// TODO: Need to limit number of bytes appended to not exceed packet size
	// Is there space/metadata info in 'b' parameter to allow this?
	err, _ = entity.SerializeAttributes(entity.attributes, entity.GetAttributeMask(), b,
		msgType, bytesAvailable, opts.FixLengths)
	return err
}
