/*
 * 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 "github.com/deckarep/golang-set"

// ManagedEntityMeClassID is the 16-bit ID for the OMCI
// Managed entity Managed entity ME
const ManagedEntityMeClassID ClassID = ClassID(288)

var managedentitymeBME *ManagedEntityDefinition

// ManagedEntityMe (class ID #288)
//	The ME describes the details of each ME that is supported by the ONU. This ME is not included in
//	an MIB upload.
//
//	Relationships
//		One or more MEs are related to the OMCI object entity.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. Its value is
//			equal to the ME type value, and is the same as the code found in the ME type table attribute of
//			the OMCI ME and Table-11.2.41. (R) (mandatory) (2-bytes)
//
//		Name
//			Name:	This attribute contains a 25-byte ASCII coded mnemonic tag for the ME type. Strings
//			shorter than 25-bytes are padded with null characters. (R) (mandatory) (25-bytes)
//
//		Attributes Table
//			NOTE - The ME ID attribute is not included in the list, since the type of this attribute is
//			fixed.
//
//		Access
//			(R) (mandatory) (1-byte)
//
//		Alarms Table
//			Alarms table: This attribute lists the alarm codes that are supported. (R) (mandatory) (Y bytes,
//			where Y is the number of entries in the table.)
//
//		Avcs Table
//			AVCs table:	This attribute lists the AVCs that are supported. (R) (mandatory) (Z bytes, where Z
//			is the number of entries in the table.)
//
//		Actions
//			Actions:	This attribute lists the action codes supported on this object, formatted as a bit map.
//			The action codes are the MTs from Table-11.2.2-1. The LSB represents action 0, and so on. (R)
//			(mandatory) (4-bytes)
//
//		Instances Table
//			Instances table: This attribute is a list of pointers to all instances of this ME. (R)
//			(mandatory) (2 * V bytes, where V is the number of entries in the table.)
//
//		Support
//			(R) (mandatory) (1-byte)
//
type ManagedEntityMe struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	managedentitymeBME = &ManagedEntityDefinition{
		Name:    "ManagedEntityMe",
		ClassID: 288,
		MessageTypes: mapset.NewSetWith(
			Get,
			GetNext,
		),
		AllowedAttributeMask: 0xff00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: MultiByteField("Name", OctetsAttributeType, 0x8000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read), false, false, false, 1),
			2: TableField("AttributesTable", TableAttributeType, 0x4000, TableInfo{nil, 2}, mapset.NewSetWith(Read), false, false, false, 2),
			3: ByteField("Access", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4: TableField("AlarmsTable", TableAttributeType, 0x1000, TableInfo{nil, 1}, mapset.NewSetWith(Read), false, false, false, 4),
			5: TableField("AvcsTable", TableAttributeType, 0x0800, TableInfo{nil, 1}, mapset.NewSetWith(Read), false, false, false, 5),
			6: Uint32Field("Actions", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, false, false, 6),
			7: TableField("InstancesTable", TableAttributeType, 0x0200, TableInfo{nil, 2}, mapset.NewSetWith(Read), false, false, false, 7),
			8: ByteField("Support", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read), false, false, false, 8),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

// NewManagedEntityMe (class ID 288) creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from or transmitted to the OMCC.
func NewManagedEntityMe(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*managedentitymeBME, params...)
}
