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

// PwAtmPerformanceMonitoringHistoryDataClassID is the 16-bit ID for the OMCI
// Managed entity PW ATM performance monitoring history data
const PwAtmPerformanceMonitoringHistoryDataClassID = ClassID(338) // 0x0152

var pwatmperformancemonitoringhistorydataBME *ManagedEntityDefinition

// PwAtmPerformanceMonitoringHistoryData (Class ID: #338 / 0x0152)
//	This ME collects PM data associated with an ATM pseudowire. Instances of this ME are created and
//	deleted by the OLT.
//
//	For a complete discussion of generic PM architecture, refer to clause I.4.
//
//	Relationships
//		An instance of this ME is associated with an instance of the PW ATM configuration data ME.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. Through an identical ID, this ME is
//			implicitly linked to the instance of the PW ATM configuration data ME. (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 ME that
//			contains PM threshold values. Since no threshold value attribute number exceeds 7, a threshold
//			data 2 ME is optional. (R,-W, setbycreate) (mandatory) (2-bytes)
//
//		Downstream Missing Packets Counter
//			This attribute counts missing packets, as detected via control word sequence number gaps. (R)
//			(mandatory) (4-bytes)
//
//		Downstream Reordered Packets Counter
//			This attribute counts packets detected out of sequence via the control word sequence number, but
//			successfully reordered. Some implementations may not support this feature. (R) (optional)
//			(4-bytes)
//
//		Downstream Misordered Packets Counter
//			This attribute counts packets detected out of order via the control word sequence numbers. (R)
//			(mandatory) (4-bytes)
//
//		Upstream Timeout Packets Counter
//			This attribute counts packets transmitted due to timeout expiration while attempting to collect
//			cells. (R) (mandatory) (4-bytes)
//
//		Upstream Transmitted Cells Counter
//			This attribute counts transmitted cells. (R) (mandatory) (4-bytes)
//
//		Upstream Dropped Cells Counter
//			This attribute counts dropped cells. (R) (mandatory) (4-bytes)
//
//		Upstream Received Cells Counter
//			This attribute counts received cells. (R) (mandatory) (4-bytes)
//
type PwAtmPerformanceMonitoringHistoryData struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const PwAtmPerformanceMonitoringHistoryData_IntervalEndTime = "IntervalEndTime"
const PwAtmPerformanceMonitoringHistoryData_ThresholdData12Id = "ThresholdData12Id"
const PwAtmPerformanceMonitoringHistoryData_DownstreamMissingPacketsCounter = "DownstreamMissingPacketsCounter"
const PwAtmPerformanceMonitoringHistoryData_DownstreamReorderedPacketsCounter = "DownstreamReorderedPacketsCounter"
const PwAtmPerformanceMonitoringHistoryData_DownstreamMisorderedPacketsCounter = "DownstreamMisorderedPacketsCounter"
const PwAtmPerformanceMonitoringHistoryData_UpstreamTimeoutPacketsCounter = "UpstreamTimeoutPacketsCounter"
const PwAtmPerformanceMonitoringHistoryData_UpstreamTransmittedCellsCounter = "UpstreamTransmittedCellsCounter"
const PwAtmPerformanceMonitoringHistoryData_UpstreamDroppedCellsCounter = "UpstreamDroppedCellsCounter"
const PwAtmPerformanceMonitoringHistoryData_UpstreamReceivedCellsCounter = "UpstreamReceivedCellsCounter"

func init() {
	pwatmperformancemonitoringhistorydataBME = &ManagedEntityDefinition{
		Name:    "PwAtmPerformanceMonitoringHistoryData",
		ClassID: PwAtmPerformanceMonitoringHistoryDataClassID,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
			GetCurrentData,
		),
		AllowedAttributeMask: 0xff80,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1: ByteField(PwAtmPerformanceMonitoringHistoryData_IntervalEndTime, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read), false, false, false, 1),
			2: Uint16Field(PwAtmPerformanceMonitoringHistoryData_ThresholdData12Id, UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3: Uint32Field(PwAtmPerformanceMonitoringHistoryData_DownstreamMissingPacketsCounter, CounterAttributeType, 0x2000, 0, mapset.NewSetWith(Read), false, false, false, 3),
			4: Uint32Field(PwAtmPerformanceMonitoringHistoryData_DownstreamReorderedPacketsCounter, CounterAttributeType, 0x1000, 0, mapset.NewSetWith(Read), false, true, false, 4),
			5: Uint32Field(PwAtmPerformanceMonitoringHistoryData_DownstreamMisorderedPacketsCounter, CounterAttributeType, 0x0800, 0, mapset.NewSetWith(Read), false, false, false, 5),
			6: Uint32Field(PwAtmPerformanceMonitoringHistoryData_UpstreamTimeoutPacketsCounter, CounterAttributeType, 0x0400, 0, mapset.NewSetWith(Read), false, false, false, 6),
			7: Uint32Field(PwAtmPerformanceMonitoringHistoryData_UpstreamTransmittedCellsCounter, CounterAttributeType, 0x0200, 0, mapset.NewSetWith(Read), false, false, false, 7),
			8: Uint32Field(PwAtmPerformanceMonitoringHistoryData_UpstreamDroppedCellsCounter, CounterAttributeType, 0x0100, 0, mapset.NewSetWith(Read), false, false, false, 8),
			9: Uint32Field(PwAtmPerformanceMonitoringHistoryData_UpstreamReceivedCellsCounter, CounterAttributeType, 0x0080, 0, mapset.NewSetWith(Read), false, false, false, 9),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			1: "Downstream missing packets",
			2: "Downstream reordered packets",
			3: "Downstream timeout packets",
			4: "Upstream dropped cells",
		},
	}
}

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