/*
 * 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
}

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...)
}
