/*
 * 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(288) // 0x0120

var managedentitymeBME *ManagedEntityDefinition

// ManagedEntityMe (Class ID: #288 / 0x0120)
//	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
//			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
//			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
//			This table contains pointers to the attribute MEs that describe each of this ME's attributes.
//			(R) (mandatory) (2 * X bytes, where X is the number of entries in the table.)
//
//			NOTE - The ME ID attribute is not included in the list, since the type of this attribute is
//			fixed.
//
//		Access
//			This attribute represents who creates this ME. The following code points are defined.
//
//			1	Created by the ONU
//
//			2	Created by the OLT
//
//			3	Created by both the ONU and OLT
//
//			(R) (mandatory) (1-byte)
//
//		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
//			This attribute lists the AVCs that are supported. (R) (mandatory) (Z bytes, where Z is the
//			number of entries in the table.)
//
//		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
//			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
//			This attribute represents the support capability of this ME in the ONU's implementation. This
//			attribute does not declare whether the OMCI implementation complies with the Recommendations,
//			but whether it complies with the OMCI declaration itself. The following code points are defined.
//
//			1	Supported (supported as defined in this object)
//
//			2	Unsupported (OMCI returns error code if accessed)
//
//			3	Partially supported (some aspects of ME supported)
//
//			4	Ignored (OMCI supported, but underlying function is not)
//
//			(R) (mandatory) (1-byte)
//
type ManagedEntityMe struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const ManagedEntityMe_Name = "Name"
const ManagedEntityMe_AttributesTable = "AttributesTable"
const ManagedEntityMe_Access = "Access"
const ManagedEntityMe_AlarmsTable = "AlarmsTable"
const ManagedEntityMe_AvcsTable = "AvcsTable"
const ManagedEntityMe_Actions = "Actions"
const ManagedEntityMe_InstancesTable = "InstancesTable"
const ManagedEntityMe_Support = "Support"

func init() {
	managedentitymeBME = &ManagedEntityDefinition{
		Name:    "ManagedEntityMe",
		ClassID: ManagedEntityMeClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			GetNext,
		),
		AllowedAttributeMask: 0xff00,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: MultiByteField(ManagedEntityMe_Name, OctetsAttributeType, 0x8000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read), false, false, false, 1),
			2: TableField(ManagedEntityMe_AttributesTable, TableAttributeType, 0x4000, TableInfo{nil, 2}, mapset.NewSetWith(Read), false, false, false, 2),
			3: ByteField(ManagedEntityMe_Access, UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4: TableField(ManagedEntityMe_AlarmsTable, TableAttributeType, 0x1000, TableInfo{nil, 1}, mapset.NewSetWith(Read), false, false, false, 4),
			5: TableField(ManagedEntityMe_AvcsTable, TableAttributeType, 0x0800, TableInfo{nil, 1}, mapset.NewSetWith(Read), false, false, false, 5),
			6: Uint32Field(ManagedEntityMe_Actions, UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, false, false, 6),
			7: TableField(ManagedEntityMe_InstancesTable, TableAttributeType, 0x0200, TableInfo{nil, 2}, mapset.NewSetWith(Read), false, false, false, 7),
			8: ByteField(ManagedEntityMe_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...)
}
