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

// EfmBondingGroupPerformanceMonitoringHistoryDataClassID is the 16-bit ID for the OMCI
// Managed entity EFM bonding group performance monitoring history data
const EfmBondingGroupPerformanceMonitoringHistoryDataClassID = ClassID(420) // 0x01a4

var efmbondinggroupperformancemonitoringhistorydataBME *ManagedEntityDefinition

// EfmBondingGroupPerformanceMonitoringHistoryData (Class ID: #420 / 0x01a4)
//	This ME collects PM data as seen at the xTU-C. Instances of this ME are created and deleted by
//	the OLT.
//
//	Relationships
//		An instance of this ME is associated with an xDSL UNI.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. Through an identical ID, this ME is
//			implicitly linked to an instance of the EFM bonding group. (R, setbycreate) (mandatory)
//			(2-bytes)
//
//		Interval End Time
//			This attribute identifies the most recently finished 15-min interval. (R) (mandatory) (1-byte)
//
//		Threshold Data 1_2 Id
//			Threshold data 1/2 ID: This attribute points to an instance of the threshold data 1 and 2 MEs
//			that contain PM threshold values. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Rx Bad Fragments
//			Clause 45.2.3.33 of [IEEE 802.3]. (R) (mandatory) (4-bytes)
//
//		Rx Lost Fragments
//			Clause 45.2.3.34 of [IEEE 802.3]. (R) (mandatory) (4-bytes)
//
//		Rx Lost Starts
//			Clause 45.2.3.35 of [IEEE 802.3]. (R) (mandatory) (4-bytes)
//
//		Rx Lost Ends
//			Clause 45.2.3.36 of [IEEE 802.3]. (R) (mandatory) (4-bytes)
//
//		Rx Frames
//			Number of Ethernet frames received over this group. (R) (mandatory) (4-bytes)
//
//		Tx Frames
//			Number of Ethernet frames transmitted over this group. (R) (mandatory) (4-bytes)
//
//		Rx Bytes
//			Number of bytes contained in the Ethernet frames received over this group. (R) (mandatory)
//			(8-bytes)
//
//		Tx Bytes
//			Number of bytes contained in the Ethernet frames transmitted over this group. (R) (mandatory)
//			(8-bytes)
//
//		Tx Discarded Frames
//			Number of Ethernet frames discarded by the group transmit function. (R) (mandatory) (4-bytes)
//
//		Tx Discarded Bytes
//			Number of bytes contained in the Ethernet frames discarded by the group transmit function. (R)
//			(mandatory) (4-bytes)
//
type EfmBondingGroupPerformanceMonitoringHistoryData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	efmbondinggroupperformancemonitoringhistorydataBME = &ManagedEntityDefinition{
		Name:    "EfmBondingGroupPerformanceMonitoringHistoryData",
		ClassID: 420,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
			GetCurrentData,
		),
		AllowedAttributeMask: 0xfff0,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  ByteField("IntervalEndTime", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2:  Uint16Field("ThresholdData12Id", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3:  Uint32Field("RxBadFragments", CounterAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4:  Uint32Field("RxLostFragments", CounterAttributeType, 0x1000, 0, mapset.NewSetWith(Read), false, false, false, 4),
			5:  Uint32Field("RxLostStarts", CounterAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, false, false, 5),
			6:  Uint32Field("RxLostEnds", CounterAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, false, false, 6),
			7:  Uint32Field("RxFrames", CounterAttributeType, 0x0200, 0, mapset.NewSetWith(Read), false, false, false, 7),
			8:  Uint32Field("TxFrames", CounterAttributeType, 0x0100, 0, mapset.NewSetWith(Read), false, false, false, 8),
			9:  Uint64Field("RxBytes", CounterAttributeType, 0x0080, 0, mapset.NewSetWith(Read), false, false, false, 9),
			10: Uint64Field("TxBytes", CounterAttributeType, 0x0040, 0, mapset.NewSetWith(Read), false, false, false, 10),
			11: Uint32Field("TxDiscardedFrames", CounterAttributeType, 0x0020, 0, mapset.NewSetWith(Read), false, false, false, 11),
			12: Uint32Field("TxDiscardedBytes", CounterAttributeType, 0x0010, 0, mapset.NewSetWith(Read), false, false, false, 12),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "Rx bad fragments",
			1: "Rx lost fragments",
			2: "Rx lost starts",
			3: "Rx lost ends",
		},
	}
}

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