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

// OnuRemoteDebugClassID is the 16-bit ID for the OMCI
// Managed entity ONU remote debug
const OnuRemoteDebugClassID = ClassID(158) // 0x009e

var onuremotedebugBME *ManagedEntityDefinition

// OnuRemoteDebug (Class ID: #158 / 0x009e)
//	This ME is used to send vendor-specific debug commands to the ONU and receive vendor-specific
//	replies back for processing on the OLT. This allows for the remote debugging of an ONU that may
//	not be accessible by other means. The command format may have two modes, one being text and the
//	other free format. In text format, both the command and reply are ASCII strings, but are
//	otherwise unconstrained. In free format, the content and format of command and reply are vendor-
//	specific.
//
//	An ONU that supports remote debugging automatically creates an instance of this ME. It is not
//	reported during an MIB upload.
//
//	Relationships
//		One instance of this ME is associated with the ONU ME.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. There is only one instance, number
//			0. (R) (mandatory) (2-bytes)
//
//		Command Format
//			This attribute defines the format of the command and reply attributes. The value 0 defines ASCII
//			string format, while 1 specifies free format. (R) (mandatory) (1-byte)
//
//		Command
//			This attribute is used to send a command to the ONU. The format of the command is defined by the
//			command format. If the format is ASCII string, the command should be null terminated unless the
//			string is exactly 25-bytes long. The action of setting this attribute should trigger the ONU to
//			discard any previous command reply information and execute the current debugging command. (W)
//			(mandatory) (25-bytes)
//
//		Reply Table
//			This attribute is used to pass reply information back to the OLT. Its format is defined by the
//			command format attribute. The get, get next action sequence must be used with this attribute,
//			since its size is unspecified. (R) (mandatory) (N bytes)
//
type OnuRemoteDebug struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const OnuRemoteDebug_CommandFormat = "CommandFormat"
const OnuRemoteDebug_Command = "Command"
const OnuRemoteDebug_ReplyTable = "ReplyTable"

func init() {
	onuremotedebugBME = &ManagedEntityDefinition{
		Name:    "OnuRemoteDebug",
		ClassID: OnuRemoteDebugClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			GetNext,
			Set,
		),
		AllowedAttributeMask: 0xe000,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: ByteField(OnuRemoteDebug_CommandFormat, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2: MultiByteField(OnuRemoteDebug_Command, OctetsAttributeType, 0x4000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Write), false, false, false, 2),
			3: TableField(OnuRemoteDebug_ReplyTable, TableAttributeType, 0x2000, TableInfo{nil, -1}, mapset.NewSetWith(Read), false, false, false, 3),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
	}
}

// NewOnuRemoteDebug (class ID 158) 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 NewOnuRemoteDebug(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*onuremotedebugBME, params...)
}
