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

// MplsPseudowireTerminationPointClassID is the 16-bit ID for the OMCI
// Managed entity MPLS pseudowire termination point
const MplsPseudowireTerminationPointClassID ClassID = ClassID(333)

var mplspseudowireterminationpointBME *ManagedEntityDefinition

// MplsPseudowireTerminationPoint (class ID #333)
//	This ME contains the configuration data of a pseudowire whose underlying transport method is
//	MPLS. Instances of this ME are created and deleted by the OLT.
//
//	Relationships
//		Zero or one instance of this ME is associated with each instance of the pseudowire TP ME.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. (R,
//			setbycreate)-(mandatory) (2 bytes)
//
//		Tp Type
//			(R, W, setbycreate) (mandatory) (1 byte)
//
//		Tp Pointer
//			TP pointer:	This attribute points to the instance of the TP associated with this MPLS PW TP. The
//			type of the associated TP is determined by the TP type attribute. (R, W, setbycreate)
//			(mandatory) (2 bytes)
//
//		Mpls Label Indicator
//			(R, W, setbycreate) (mandatory) (1 byte)
//
//		Mpls Pw Direction
//			(R, W, setbycreate) (mandatory) (1 byte)
//
//		Mpls Pw Uplink Label
//			MPLS PW uplink label: This attribute specifies the label of the inner MPLS pseudowire upstream.
//			The attribute is not meaningful for unidirectional downstream PWs. (R, W, setbycreate)
//			(mandatory) (4 bytes)
//
//		Mpls Pw Downlink Label
//			MPLS PW downlink label: This attribute specifies the label of the inner MPLS pseudowire
//			downstream. The attribute is not meaningful for unidirectional upstream PWs. (R, W, setbycreate)
//			(mandatory) (4 bytes)
//
//		Mpls Pw Tc
//			NOTE 1 - The TC field was previously known as EXP. Refer to [bIETF-RFC-5462].
//
//		Mpls Tunnel Direction
//			(R, W, setbycreate) (mandatory for double-labelled case) (1 byte)
//
//		Mpls Tunnel Uplink Label
//			MPLS tunnel uplink label: This attribute specifies the (outer) label for the upstream MPLS
//			tunnel. If the MPLS tunnel is downstream only, this attribute should be set to 0. (R, W,
//			setbycreate) (mandatory for double-labelled case) (4 bytes)
//
//		Mpls Tunnel Downlink Label
//			MPLS tunnel downlink label: This attribute specifies the (outer) label for the downstream MPLS
//			tunnel. If the MPLS tunnel is upstream only, this attribute should be set to 0. (R, W,
//			setbycreate) (mandatory for double-labelled case) (4 bytes)
//
//		Mpls Tunnel Tc
//			NOTE 2 - The TC field was previously known as EXP. Refer to [bIETF-RFC-5462].
//
//		Pseudowire Type
//			(R, W, setbycreate) (mandatory) (2 bytes)
//
//		Pseudowire Control Word Preference
//			Pseudowire control word preference: When set to true, this Boolean attribute specifies that a
//			control word is to be sent with each packet. Some PW types mandate the use of a control word in
//			any event. In such cases, the value configured for this attribute has no effect on the presence
//			of the control word. (R, W, setbycreate) (optional) (1 byte)
//
//		Administrative State
//			Administrative state: This attribute locks (1) and unlocks (0) the functions performed by the
//			MPLS pseudowire TP. Administrative state is further described in clause-A.1.6. (R,-W) (optional)
//			(1-byte)
//
//		Operational State
//			Operational state: This attribute reports whether the ME is currently capable of performing its
//			function. Valid values are enabled (0) and disabled (1). (R) (optional) (1-byte)
//
type MplsPseudowireTerminationPoint struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	mplspseudowireterminationpointBME = &ManagedEntityDefinition{
		Name:    "MplsPseudowireTerminationPoint",
		ClassID: 333,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xfffe,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1:  ByteField("TpType", UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 1),
			2:  Uint16Field("TpPointer", UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 2),
			3:  ByteField("MplsLabelIndicator", UnsignedIntegerAttributeType, 0x2000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 3),
			4:  ByteField("MplsPwDirection", UnsignedIntegerAttributeType, 0x1000, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 4),
			5:  Uint32Field("MplsPwUplinkLabel", UnsignedIntegerAttributeType, 0x0800, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 5),
			6:  Uint32Field("MplsPwDownlinkLabel", UnsignedIntegerAttributeType, 0x0400, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 6),
			7:  ByteField("MplsPwTc", UnsignedIntegerAttributeType, 0x0200, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 7),
			8:  ByteField("MplsTunnelDirection", UnsignedIntegerAttributeType, 0x0100, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 8),
			9:  Uint32Field("MplsTunnelUplinkLabel", UnsignedIntegerAttributeType, 0x0080, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 9),
			10: Uint32Field("MplsTunnelDownlinkLabel", UnsignedIntegerAttributeType, 0x0040, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 10),
			11: ByteField("MplsTunnelTc", UnsignedIntegerAttributeType, 0x0020, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 11),
			12: Uint16Field("PseudowireType", UnsignedIntegerAttributeType, 0x0010, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, 12),
			13: ByteField("PseudowireControlWordPreference", UnsignedIntegerAttributeType, 0x0008, 0, mapset.NewSetWith(Read, SetByCreate, Write), false, true, false, 13),
			14: ByteField("AdministrativeState", UnsignedIntegerAttributeType, 0x0004, 0, mapset.NewSetWith(Read, Write), false, true, false, 14),
			15: ByteField("OperationalState", UnsignedIntegerAttributeType, 0x0002, 0, mapset.NewSetWith(Read), true, true, false, 15),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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