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

// AuthenticationSecurityMethodClassID is the 16-bit ID for the OMCI
// Managed entity Authentication security method
const AuthenticationSecurityMethodClassID = ClassID(148) // 0x0094

var authenticationsecuritymethodBME *ManagedEntityDefinition

// AuthenticationSecurityMethod (Class ID: #148 / 0x0094)
//	The authentication security method defines the user ID and password configuration to establish a
//	session between a client and a server. This object may be used in the role of the client or
//	server. An instance of this ME is created by the OLT if authenticated communication is
//	necessary.
//
//	Relationships
//		One instance of this management entity may be associated with a network address ME. This ME may
//		also be cited by other MEs that require authentication parameter management.
//
//	Attributes
//		Managed Entity Id
//			This attribute uniquely identifies each instance of this ME. The value 0xFFFF is reserved. (R,
//			setbycreate) (mandatory) (2-bytes)
//
//		Validation Scheme
//			This attribute specifies the validation scheme used when the ONU validates a challenge.
//			Validation schemes are defined as follows.
//
//			0	Validation disabled
//
//			1	Validate using MD5 digest authentication as defined in [IETF-RFC-2617] (recommended)
//
//			3	Validate using basic authentication as defined in [IETF RFC 2617]
//
//			(R,-W) (mandatory) (1-byte)
//
//		Username 1
//			This string attribute is the user name. If the string is shorter than 25-bytes, it must be null
//			terminated (Note). (R,-W) (mandatory) (25-bytes)
//
//		Password
//			This string attribute is the password. If the string is shorter than 25-bytes, it must be null
//			terminated. (R,-W) (mandatory) (25-bytes)
//
//		Realm
//			This string attribute specifies the realm used in digest authentication. If the string is
//			shorter than 25-bytes, it must be null terminated. (R,-W) (mandatory) (25-bytes)
//
//		Username 2
//			This string attribute allows for continuation of the user name beyond 25-characters (Note). Its
//			default value is a null string. (R,-W) (optional) (25-bytes)
//
//			NOTE - The total username is the concatenation of the username 1 and username 2 attributes if
//			and only if: a) username 1 comprises 25 non-null characters; b) username 2 is supported by the
//			ONU; and c) username 2 contains a leading non-null character string. Otherwise, the total
//			username is simply the value of the username 1 attribute.
//
type AuthenticationSecurityMethod struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const AuthenticationSecurityMethod_ValidationScheme = "ValidationScheme"
const AuthenticationSecurityMethod_Username1 = "Username1"
const AuthenticationSecurityMethod_Password = "Password"
const AuthenticationSecurityMethod_Realm = "Realm"
const AuthenticationSecurityMethod_Username2 = "Username2"

func init() {
	authenticationsecuritymethodBME = &ManagedEntityDefinition{
		Name:    "AuthenticationSecurityMethod",
		ClassID: AuthenticationSecurityMethodClassID,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0xf800,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, 0),
			1: ByteField(AuthenticationSecurityMethod_ValidationScheme, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, false, false, 1),
			2: MultiByteField(AuthenticationSecurityMethod_Username1, OctetsAttributeType, 0x4000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, false, false, 2),
			3: MultiByteField(AuthenticationSecurityMethod_Password, OctetsAttributeType, 0x2000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, false, false, 3),
			4: MultiByteField(AuthenticationSecurityMethod_Realm, OctetsAttributeType, 0x1000, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, false, false, 4),
			5: MultiByteField(AuthenticationSecurityMethod_Username2, OctetsAttributeType, 0x0800, 25, toOctets("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), mapset.NewSetWith(Read, Write), false, true, false, 5),
		},
		Access:  CreatedByOlt,
		Support: UnknownSupport,
	}
}

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