import datetime
from enum import IntEnum
from KL.types import *
from KL.constants import ObjectIds


class ApplicationType(IntEnum):
    """
    :ivar Server:
    :vartype Server: 0
    :ivar Client:
    :vartype Client: 1
    :ivar ClientAndServer:
    :vartype ClientAndServer: 2
    :ivar DiscoveryServer:
    :vartype DiscoveryServer: 3
    """
    Server = 0
    Client = 1
    ClientAndServer = 2
    DiscoveryServer = 3


class BrowseDirection(IntEnum):
    """
    :ivar Forward:
    :vartype Forward: 0
    :ivar Inverse:
    :vartype Inverse: 1
    :ivar Both:
    :vartype Both: 2
    :ivar Invalid:
    :vartype Invalid: 3
    """
    Forward = 0
    Inverse = 1
    Both = 2
    Invalid = 3


class BrowseResultMask(IntEnum):
    """
    :ivar None_:
    :vartype None_: 0
    :ivar ReferenceTypeId:
    :vartype ReferenceTypeId: 1
    :ivar IsForward:
    :vartype IsForward: 2
    :ivar NodeClass:
    :vartype NodeClass: 4
    :ivar BrowseName:
    :vartype BrowseName: 8
    :ivar DisplayName:
    :vartype DisplayName: 16
    :ivar TypeDefinition:
    :vartype TypeDefinition: 32
    :ivar All:
    :vartype All: 63
    :ivar ReferenceTypeInfo:
    :vartype ReferenceTypeInfo: 3
    :ivar TargetInfo:
    :vartype TargetInfo: 60
    """
    None_ = 0
    ReferenceTypeId = 1
    IsForward = 2
    NodeClass = 4
    BrowseName = 8
    DisplayName = 16
    TypeDefinition = 32
    All = 63
    ReferenceTypeInfo = 3
    TargetInfo = 60


class ApplicationDescription(FrozenClass):
    """
    :ivar ApplicationUri:
    :vartype ApplicationUri: String
    :ivar ProductUri:
    :vartype ProductUri: String
    :ivar ApplicationName:
    :vartype ApplicationName: LocalizedText
    :ivar ApplicationType:
    :vartype ApplicationType: ApplicationType
    :ivar GatewayServerUri:
    :vartype GatewayServerUri: String
    :ivar DiscoveryProfileUri:
    :vartype DiscoveryProfileUri: String
    :ivar DiscoveryUrls:
    :vartype DiscoveryUrls: String
    """

    types = [
        ('ApplicationUri', 'String'),
        ('ProductUri', 'String'),
        ('ApplicationName', 'LocalizedText'),
        ('ApplicationType', 'ApplicationType'),
        ('GatewayServerUri', 'String'),
        ('DiscoveryProfileUri', 'String'),
        ('DiscoveryUrls', 'ListOfString'),
               ]

    def __init__(self):
        self.ApplicationUri = None
        self.ProductUri = None
        self.ApplicationName = LocalizedText()
        self.ApplicationType = ApplicationType(0)
        self.GatewayServerUri = None
        self.DiscoveryProfileUri = None
        self.DiscoveryUrls = []
        self._freeze = True

    def __str__(self):
        return 'ApplicationDescription(ApplicationUri:{self.ApplicationUri}, ProductUri:{self.ProductUri}, ApplicationName:{self.ApplicationName}, ApplicationType:{self.ApplicationType}, GatewayServerUri:{self.GatewayServerUri}, DiscoveryProfileUri:{self.DiscoveryProfileUri}, DiscoveryUrls:{self.DiscoveryUrls})'

    __repr__ = __str__


class EndpointDescription(FrozenClass):
    """
    :ivar EndpointUrl:
    :vartype EndpointUrl: String
    :ivar Server:
    :vartype Server: ApplicationDescription
    :ivar ServerCertificate:
    :vartype ServerCertificate: ByteString
    :ivar SecurityMode:
    :vartype SecurityMode: MessageSecurityMode
    :ivar SecurityPolicyUri:
    :vartype SecurityPolicyUri: String
    :ivar UserIdentityTokens:
    :vartype UserIdentityTokens: UserTokenPolicy
    :ivar TransportProfileUri:
    :vartype TransportProfileUri: String
    :ivar SecurityLevel:
    :vartype SecurityLevel: Byte
    """

    types = [
        ('EndpointUrl', 'String'),
        ('Server', 'ApplicationDescription'),
        ('ServerCertificate', 'ByteString'),
        ('SecurityMode', 'MessageSecurityMode'),
        ('SecurityPolicyUri', 'String'),
        ('UserIdentityTokens', 'ListOfUserTokenPolicy'),
        ('TransportProfileUri', 'String'),
        ('SecurityLevel', 'Byte'),
               ]

    def __init__(self):
        self.EndpointUrl = None
        self.Server = ApplicationDescription()
        self.ServerCertificate = None
        self.SecurityMode = MessageSecurityMode(0)
        self.SecurityPolicyUri = None
        self.UserIdentityTokens = []
        self.TransportProfileUri = None
        self.SecurityLevel = 0
        self._freeze = True

    def __str__(self):
        return 'EndpointDescription(EndpointUrl:{self.EndpointUrl}, Server:{self.Server}, ServerCertificate:{self.ServerCertificate}, SecurityMode:{self.SecurityMode}, SecurityPolicyUri:{self.SecurityPolicyUri}, UserIdentityTokens:{self.UserIdentityTokens}, TransportProfileUri:{self.TransportProfileUri}, SecurityLevel:{self.SecurityLevel})'

    __repr__ = __str__


class AddReferencesItem(FrozenClass):
    """
    :ivar SourceNodeId:
    :vartype SourceNodeId: NodeId
    :ivar ReferenceTypeId:
    :vartype ReferenceTypeId: NodeId
    :ivar IsForward:
    :vartype IsForward: Boolean
    :ivar TargetServerUri:
    :vartype TargetServerUri: String
    :ivar TargetNodeId:
    :vartype TargetNodeId: ExpandedNodeId
    :ivar TargetNodeClass:
    :vartype TargetNodeClass: NodeClass
    """

    types = [
        ('SourceNodeId', 'NodeId'),
        ('ReferenceTypeId', 'NodeId'),
        ('IsForward', 'Boolean'),
        ('TargetServerUri', 'String'),
        ('TargetNodeId', 'ExpandedNodeId'),
        ('TargetNodeClass', 'NodeClass'),
    ]

    def __init__(self):
        self.SourceNodeId = NodeId()
        self.ReferenceTypeId = NodeId()
        self.IsForward = True
        self.TargetServerUri = None
        self.TargetNodeId = ExpandedNodeId()
        self.TargetNodeClass = NodeClass(0)
        self._freeze = True


class MessageSecurityMode(IntEnum):
    """
    :ivar Invalid:
    :vartype Invalid: 0
    :ivar None_:
    :vartype None_: 1
    :ivar Sign:
    :vartype Sign: 2
    :ivar SignAndEncrypt:
    :vartype SignAndEncrypt: 3
    """
    Invalid = 0
    None_ = 1
    Sign = 2
    SignAndEncrypt = 3


class UserTokenType(IntEnum):
    """
    :ivar Anonymous:
    :vartype Anonymous: 0
    :ivar UserName:
    :vartype UserName: 1
    :ivar Certificate:
    :vartype Certificate: 2
    :ivar IssuedToken:
    :vartype IssuedToken: 3
    """
    Anonymous = 0
    UserName = 1
    Certificate = 2
    IssuedToken = 3


class UserTokenPolicy(FrozenClass):
    """
    :ivar PolicyId:
    :vartype PolicyId: String
    :ivar TokenType:
    :vartype TokenType: UserTokenType
    :ivar IssuedTokenType:
    :vartype IssuedTokenType: String
    :ivar IssuerEndpointUrl:
    :vartype IssuerEndpointUrl: String
    :ivar SecurityPolicyUri:
    :vartype SecurityPolicyUri: String
    """

    types = [
        ('PolicyId', 'String'),
        ('TokenType', 'UserTokenType'),
        ('IssuedTokenType', 'String'),
        ('IssuerEndpointUrl', 'String'),
        ('SecurityPolicyUri', 'String'),
               ]

    def __init__(self):
        self.PolicyId = None
        self.TokenType = UserTokenType(0)
        self.IssuedTokenType = None
        self.IssuerEndpointUrl = None
        self.SecurityPolicyUri = None
        self._freeze = True

    def __str__(self):
        return 'UserTokenPolicy(PolicyId:{self.PolicyId}, TokenType:{self.TokenType}, IssuedTokenType:{self.IssuedTokenType}, IssuerEndpointUrl:{self.IssuerEndpointUrl}, SecurityPolicyUri:{self.SecurityPolicyUri})'

    __repr__ = __str__


class ServerState(IntEnum):
    """
    :ivar Running:
    :vartype Running: 0
    :ivar Failed:
    :vartype Failed: 1
    :ivar NoConfiguration:
    :vartype NoConfiguration: 2
    :ivar Suspended:
    :vartype Suspended: 3
    :ivar Shutdown:
    :vartype Shutdown: 4
    :ivar Test:
    :vartype Test: 5
    :ivar CommunicationFault:
    :vartype CommunicationFault: 6
    :ivar Unknown:
    :vartype Unknown: 7
    """
    Running = 0
    Failed = 1
    NoConfiguration = 2
    Suspended = 3
    Shutdown = 4
    Test = 5
    CommunicationFault = 6
    Unknown = 7


class ServerStatusDataType(FrozenClass):
    """
    :ivar StartTime:
    :vartype StartTime: DateTime
    :ivar CurrentTime:
    :vartype CurrentTime: DateTime
    :ivar State:
    :vartype State: ServerState
    :ivar BuildInfo:
    :vartype BuildInfo: BuildInfo
    :ivar SecondsTillShutdown:
    :vartype SecondsTillShutdown: UInt32
    :ivar ShutdownReason:
    :vartype ShutdownReason: LocalizedText
    """

    types = [
        ('StartTime', 'DateTime'),
        ('CurrentTime', 'DateTime'),
        ('State', 'ServerState'),
        ('BuildInfo', 'BuildInfo'),
        ('SecondsTillShutdown', 'UInt32'),
        ('ShutdownReason', 'LocalizedText'),
               ]

    def __init__(self):
        self.StartTime = datetime.datetime.utcnow()
        self.CurrentTime = datetime.datetime.utcnow()
        self.State = ServerState(0)
        self.BuildInfo = BuildInfo()
        self.SecondsTillShutdown = 0
        self.ShutdownReason = LocalizedText()
        self._freeze = True

    def __str__(self):
        return 'ServerStatusDataType(StartTime:{self.StartTime}, CurrentTime:{self.CurrentTime}, State:{self.State}, BuildInfo:{self.BuildInfo}, SecondsTillShutdown:{self.SecondsTillShutdown}, ShutdownReason:{self.ShutdownReason})'

    __repr__ = __str__


class BuildInfo(FrozenClass):
    """
    :ivar ProductUri:
    :vartype ProductUri: String
    :ivar ManufacturerName:
    :vartype ManufacturerName: String
    :ivar ProductName:
    :vartype ProductName: String
    :ivar SoftwareVersion:
    :vartype SoftwareVersion: String
    :ivar BuildNumber:
    :vartype BuildNumber: String
    :ivar BuildDate:
    :vartype BuildDate: DateTime
    """

    types = [
        ('ProductUri', 'String'),
        ('ManufacturerName', 'String'),
        ('ProductName', 'String'),
        ('SoftwareVersion', 'String'),
        ('BuildNumber', 'String'),
        ('BuildDate', 'DateTime'),
               ]

    def __init__(self):
        self.ProductUri = None
        self.ManufacturerName = None
        self.ProductName = None
        self.SoftwareVersion = None
        self.BuildNumber = None
        self.BuildDate = datetime.datetime.utcnow()
        self._freeze = True

    def __str__(self):
        return 'BuildInfo(ProductUri:{self.ProductUri}, ManufacturerName:{self.ManufacturerName}, ProductName:{self.ProductName}, SoftwareVersion:{self.SoftwareVersion}, BuildNumber:{self.BuildNumber}, BuildDate:{self.BuildDate})'

    __repr__ = __str__


class ReferenceTypeAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar IsAbstract:
    :vartype IsAbstract: Boolean
    :ivar Symmetric:
    :vartype Symmetric: Boolean
    :ivar InverseName:
    :vartype InverseName: LocalizedText
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('IsAbstract', 'Boolean'),
        ('Symmetric', 'Boolean'),
        ('InverseName', 'LocalizedText'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.IsAbstract = True
        self.Symmetric = True
        self.InverseName = LocalizedText()
        self._freeze = True

    def __str__(self):
        return 'ReferenceTypeAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{' \
               'self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{' \
               'self.UserWriteMask}, IsAbstract:{self.IsAbstract}, Symmetric:{self.Symmetric}, InverseName:{' \
               'self.InverseName}) '

    __repr__ = __str__


ExpandedNodeId = NodeId


class NodeClass(IntEnum):
    """
    :ivar Unspecified:
    :vartype Unspecified: 0
    :ivar Object:
    :vartype Object: 1
    :ivar Variable:
    :vartype Variable: 2
    :ivar Method:
    :vartype Method: 4
    :ivar ObjectType:
    :vartype ObjectType: 8
    :ivar VariableType:
    :vartype VariableType: 16
    :ivar ReferenceType:
    :vartype ReferenceType: 32
    :ivar DataType:
    :vartype DataType: 64
    :ivar View:
    :vartype View: 128
    """
    Unspecified = 0
    Object = 1
    Variable = 2
    Method = 4
    ObjectType = 8
    VariableType = 16
    ReferenceType = 32
    DataType = 64
    View = 128


class NodeAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self._freeze = True

    def __str__(self):
        return 'NodeAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, ' \
               'Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}) '

    __repr__ = __str__


class NodeAttributesMask(IntEnum):
    """
    :ivar None_:
    :vartype None_: 0
    :ivar AccessLevel:
    :vartype AccessLevel: 1
    :ivar ArrayDimensions:
    :vartype ArrayDimensions: 2
    :ivar BrowseName:
    :vartype BrowseName: 4
    :ivar ContainsNoLoops:
    :vartype ContainsNoLoops: 8
    :ivar DataType:
    :vartype DataType: 16
    :ivar Description:
    :vartype Description: 32
    :ivar DisplayName:
    :vartype DisplayName: 64
    :ivar EventNotifier:
    :vartype EventNotifier: 128
    :ivar Executable:
    :vartype Executable: 256
    :ivar Historizing:
    :vartype Historizing: 512
    :ivar InverseName:
    :vartype InverseName: 1024
    :ivar IsAbstract:
    :vartype IsAbstract: 2048
    :ivar MinimumSamplingInterval:
    :vartype MinimumSamplingInterval: 4096
    :ivar NodeClass:
    :vartype NodeClass: 8192
    :ivar NodeId:
    :vartype NodeId: 16384
    :ivar Symmetric:
    :vartype Symmetric: 32768
    :ivar UserAccessLevel:
    :vartype UserAccessLevel: 65536
    :ivar UserExecutable:
    :vartype UserExecutable: 131072
    :ivar UserWriteMask:
    :vartype UserWriteMask: 262144
    :ivar ValueRank:
    :vartype ValueRank: 524288
    :ivar WriteMask:
    :vartype WriteMask: 1048576
    :ivar Value:
    :vartype Value: 2097152
    :ivar DataTypeDefinition:
    :vartype DataTypeDefinition: 4194304
    :ivar RolePermissions:
    :vartype RolePermissions: 8388608
    :ivar AccessRestrictions:
    :vartype AccessRestrictions: 16777216
    :ivar All:
    :vartype All: 33554431
    :ivar BaseNode:
    :vartype BaseNode: 26501220
    :ivar Object:
    :vartype Object: 26501348
    :ivar ObjectType:
    :vartype ObjectType: 26503268
    :ivar Variable:
    :vartype Variable: 26571383
    :ivar VariableType:
    :vartype VariableType: 28600438
    :ivar Method:
    :vartype Method: 26632548
    :ivar ReferenceType:
    :vartype ReferenceType: 26537060
    :ivar View:
    :vartype View: 26501356
    """
    None_ = 0
    AccessLevel = 1
    ArrayDimensions = 2
    BrowseName = 4
    ContainsNoLoops = 8
    DataType = 16
    Description = 32
    DisplayName = 64
    EventNotifier = 128
    Executable = 256
    Historizing = 512
    InverseName = 1024
    IsAbstract = 2048
    MinimumSamplingInterval = 4096
    NodeClass = 8192
    NodeId = 16384
    Symmetric = 32768
    UserAccessLevel = 65536
    UserExecutable = 131072
    UserWriteMask = 262144
    ValueRank = 524288
    WriteMask = 1048576
    Value = 2097152
    DataTypeDefinition = 4194304
    RolePermissions = 8388608
    AccessRestrictions = 16777216
    All = 33554431
    BaseNode = 26501220
    Object = 26501348
    ObjectType = 26503268
    Variable = 26571383
    VariableType = 28600438
    Method = 26632548
    ReferenceType = 26537060
    View = 26501356


class AddNodesItem(FrozenClass):
    """
    :ivar ParentNodeId:
    :vartype ParentNodeId: ExpandedNodeId
    :ivar ReferenceTypeId:
    :vartype ReferenceTypeId: NodeId
    :ivar RequestedNewNodeId:
    :vartype RequestedNewNodeId: ExpandedNodeId
    :ivar BrowseName:
    :vartype BrowseName: QualifiedName
    :ivar NodeClass:
    :vartype NodeClass: NodeClass
    :ivar NodeAttributes:
    :vartype NodeAttributes: ExtensionObject
    :ivar TypeDefinition:
    :vartype TypeDefinition: ExpandedNodeId
    """

    types = [
        ('ParentNodeId', 'ExpandedNodeId'),
        ('ReferenceTypeId', 'NodeId'),
        ('RequestedNewNodeId', 'ExpandedNodeId'),
        ('BrowseName', 'QualifiedName'),
        ('NodeClass', 'NodeClass'),
        ('NodeAttributes', 'ExtensionObject'),
        ('TypeDefinition', 'ExpandedNodeId'),
    ]

    def __init__(self):
        self.ParentNodeId = ExpandedNodeId()
        self.ReferenceTypeId = NodeId()
        self.RequestedNewNodeId = ExpandedNodeId()
        self.BrowseName = QualifiedName()
        self.NodeClass = NodeClass(0)
        self.NodeAttributes = ExtensionObject()
        self.TypeDefinition = ExpandedNodeId()
        self._freeze = True

    def __str__(self):
        return 'AddNodesItem(ParentNodeId:{self.ParentNodeId}, ReferenceTypeId:{self.ReferenceTypeId}, RequestedNewNodeId:{self.RequestedNewNodeId}, BrowseName:{self.BrowseName}, NodeClass:{self.NodeClass}, NodeAttributes:{self.NodeAttributes}, TypeDefinition:{self.TypeDefinition})'

    __repr__ = __str__


class ReadParameters(FrozenClass):
    """
    :ivar MaxAge:
    :vartype MaxAge: Double
    :ivar TimestampsToReturn:
    :vartype TimestampsToReturn: TimestampsToReturn
    :ivar NodesToRead:
    :vartype NodesToRead: ReadValueId
    """

    types = [
        ('MaxAge', 'Double'),
        ('TimestampsToReturn', 'TimestampsToReturn'),
        ('NodesToRead', 'ListOfReadValueId'),
    ]

    def __init__(self):
        self.MaxAge = 0
        self.TimestampsToReturn = TimestampsToReturn(0)
        self.NodesToRead = []
        self._freeze = True

    def __str__(self):
        return 'ReadParameters(MaxAge:{self.MaxAge}, TimestampsToReturn:{self.TimestampsToReturn}, NodesToRead:{self.NodesToRead})'

    __repr__ = __str__


class WriteParameters(FrozenClass):
    """
    :ivar NodesToWrite:
    :vartype NodesToWrite: WriteValue
    """

    ua_types = [
        ('NodesToWrite', 'ListOfWriteValue'),
               ]

    def __init__(self):
        self.NodesToWrite = []
        self._freeze = True

    def __str__(self):
        return 'WriteParameters(NodesToWrite:{self.NodesToWrite})'

    __repr__ = __str__


class ReadValueId(FrozenClass):
    """
    :ivar NodeId:
    :vartype NodeId: NodeId
    :ivar AttributeId:
    :vartype AttributeId: UInt32
    :ivar IndexRange:
    :vartype IndexRange: String
    :ivar DataEncoding:
    :vartype DataEncoding: QualifiedName
    """

    types = [
        ('NodeId', 'NodeId'),
        ('AttributeId', 'UInt32'),
        ('IndexRange', 'String'),
        ('DataEncoding', 'QualifiedName'),
    ]

    def __init__(self):
        self.NodeId = NodeId()
        self.AttributeId = 0
        self.IndexRange = None
        self.DataEncoding = QualifiedName()
        self._freeze = True

    def __str__(self):
        return 'ReadValueId(NodeId:{self.NodeId}, AttributeId:{self.AttributeId}, IndexRange:{self.IndexRange}, DataEncoding:{self.DataEncoding})'

    __repr__ = __str__


class TimestampsToReturn(IntEnum):
    """
    :ivar Source:
    :vartype Source: 0
    :ivar Server:
    :vartype Server: 1
    :ivar Both:
    :vartype Both: 2
    :ivar Neither:
    :vartype Neither: 3
    :ivar Invalid:
    :vartype Invalid: 4
    """
    Source = 0
    Server = 1
    Both = 2
    Neither = 3
    Invalid = 4


class ReferenceDescription(FrozenClass):
    """
    :ivar ReferenceTypeId:
    :vartype ReferenceTypeId: NodeId
    :ivar IsForward:
    :vartype IsForward: Boolean
    :ivar NodeId:
    :vartype NodeId: ExpandedNodeId
    :ivar BrowseName:
    :vartype BrowseName: QualifiedName
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar NodeClass:
    :vartype NodeClass: NodeClass
    :ivar TypeDefinition:
    :vartype TypeDefinition: ExpandedNodeId
    """

    types = [
        ('ReferenceTypeId', 'NodeId'),
        ('IsForward', 'Boolean'),
        ('NodeId', 'ExpandedNodeId'),
        ('BrowseName', 'QualifiedName'),
        ('DisplayName', 'LocalizedText'),
        ('NodeClass', 'NodeClass'),
        ('TypeDefinition', 'ExpandedNodeId'),
    ]

    def __init__(self):
        self.ReferenceTypeId = NodeId()
        self.IsForward = True
        self.NodeId = ExpandedNodeId()
        self.BrowseName = QualifiedName()
        self.DisplayName = LocalizedText()
        self.NodeClass = NodeClass(0)
        self.TypeDefinition = ExpandedNodeId()
        self._freeze = True

    def __str__(self):
        return 'ReferenceDescription(ReferenceTypeId:{self.ReferenceTypeId}, IsForward:{self.IsForward}, NodeId:{self.NodeId}, BrowseName:{self.BrowseName}, DisplayName:{self.DisplayName}, NodeClass:{self.NodeClass}, TypeDefinition:{self.TypeDefinition})'

    __repr__ = __str__


class VariableAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar Value:
    :vartype Value: Variant
    :ivar DataType:
    :vartype DataType: NodeId
    :ivar ValueRank:
    :vartype ValueRank: Int32
    :ivar ArrayDimensions:
    :vartype ArrayDimensions: UInt32
    :ivar AccessLevel:
    :vartype AccessLevel: Byte
    :ivar UserAccessLevel:
    :vartype UserAccessLevel: Byte
    :ivar MinimumSamplingInterval:
    :vartype MinimumSamplingInterval: Double
    :ivar Historizing:
    :vartype Historizing: Boolean
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('Value', 'Variant'),
        ('DataType', 'NodeId'),
        ('ValueRank', 'Int32'),
        ('ArrayDimensions', 'ListOfUInt32'),
        ('AccessLevel', 'Byte'),
        ('UserAccessLevel', 'Byte'),
        ('MinimumSamplingInterval', 'Double'),
        ('Historizing', 'Boolean'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.Value = Variant()
        self.DataType = NodeId()
        self.ValueRank = 0
        self.ArrayDimensions = []
        self.AccessLevel = 0
        self.UserAccessLevel = 0
        self.MinimumSamplingInterval = 0
        self.Historizing = True
        self._freeze = True

    def __str__(self):
        return 'VariableAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, ' \
               'Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, ' \
               'Value:{self.Value}, DataType:{self.DataType}, ValueRank:{self.ValueRank}, ArrayDimensions:{' \
               'self.ArrayDimensions}, AccessLevel:{self.AccessLevel}, UserAccessLevel:{self.UserAccessLevel}, ' \
               'MinimumSamplingInterval:{self.MinimumSamplingInterval}, Historizing:{self.Historizing}) '

    __repr__ = __str__


class VariableTypeAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar Value:
    :vartype Value: Variant
    :ivar DataType:
    :vartype DataType: NodeId
    :ivar ValueRank:
    :vartype ValueRank: Int32
    :ivar ArrayDimensions:
    :vartype ArrayDimensions: UInt32
    :ivar IsAbstract:
    :vartype IsAbstract: Boolean
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('Value', 'Variant'),
        ('DataType', 'NodeId'),
        ('ValueRank', 'Int32'),
        ('ArrayDimensions', 'ListOfUInt32'),
        ('IsAbstract', 'Boolean'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.Value = Variant()
        self.DataType = NodeId()
        self.ValueRank = 0
        self.ArrayDimensions = []
        self.IsAbstract = True
        self._freeze = True

    def __str__(self):
        return 'VariableTypeAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, Value:{self.Value}, DataType:{self.DataType}, ValueRank:{self.ValueRank}, ArrayDimensions:{self.ArrayDimensions}, IsAbstract:{self.IsAbstract})'

    __repr__ = __str__


class ObjectAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar EventNotifier:
    :vartype EventNotifier: Byte
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('EventNotifier', 'Byte'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.EventNotifier = 0
        self._freeze = True

    def __str__(self):
        return 'ObjectAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, ' \
               'Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, ' \
               'EventNotifier:{self.EventNotifier}) '

    __repr__ = __str__


class DataTypeAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar IsAbstract:
    :vartype IsAbstract: Boolean
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('IsAbstract', 'Boolean'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.IsAbstract = True
        self._freeze = True

    def __str__(self):
        return 'DataTypeAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, IsAbstract:{self.IsAbstract})'

    __repr__ = __str__


class ObjectTypeAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar IsAbstract:
    :vartype IsAbstract: Boolean
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('IsAbstract', 'Boolean'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.IsAbstract = True
        self._freeze = True

    def __str__(self):
        return 'ObjectTypeAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, ' \
               'Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, ' \
               'IsAbstract:{self.IsAbstract}) '

    __repr__ = __str__


class AddNodesResult(FrozenClass):
    """
    :ivar StatusCode:
    :vartype StatusCode: StatusCode
    :ivar AddedNodeId:
    :vartype AddedNodeId: NodeId
    """

    types = [
        ('StatusCode', 'StatusCode'),
        ('AddedNodeId', 'NodeId'),
    ]

    def __init__(self):
        self.StatusCode = StatusCode()
        self.AddedNodeId = NodeId()
        self._freeze = True

    def __str__(self):
        return 'AddNodesResult(StatusCode:{self.StatusCode}, AddedNodeId:{self.AddedNodeId})'

    __repr__ = __str__


class GenericAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar AttributeValues:
    :vartype AttributeValues: GenericAttributeValue
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('AttributeValues', 'ListOfGenericAttributeValue'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.AttributeValues = []
        self._freeze = True

    def __str__(self):
        return 'GenericAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, AttributeValues:{self.AttributeValues})'

    __repr__ = __str__


class ViewAttributes(FrozenClass):
    """
    :ivar SpecifiedAttributes:
    :vartype SpecifiedAttributes: UInt32
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    :ivar WriteMask:
    :vartype WriteMask: UInt32
    :ivar UserWriteMask:
    :vartype UserWriteMask: UInt32
    :ivar ContainsNoLoops:
    :vartype ContainsNoLoops: Boolean
    :ivar EventNotifier:
    :vartype EventNotifier: Byte
    """

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('ContainsNoLoops', 'Boolean'),
        ('EventNotifier', 'Byte'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.ContainsNoLoops = True
        self.EventNotifier = 0
        self._freeze = True

    def __str__(self):
        return 'ViewAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, ContainsNoLoops:{self.ContainsNoLoops}, EventNotifier:{self.EventNotifier})'

    __repr__ = __str__


class WriteValue(FrozenClass):
    """
    :ivar NodeId:
    :vartype NodeId: NodeId
    :ivar AttributeId:
    :vartype AttributeId: UInt32
    :ivar IndexRange:
    :vartype IndexRange: String
    :ivar Value:
    :vartype Value: DataValue
    """

    types = [
        ('NodeId', 'NodeId'),
        ('AttributeId', 'UInt32'),
        ('IndexRange', 'String'),
        ('Value', 'DataValue'),
    ]

    def __init__(self):
        self.NodeId = NodeId()
        self.AttributeId = 0
        self.IndexRange = None
        self.Value = DataValue()
        self._freeze = True

    def __str__(self):
        return 'WriteValue(NodeId:{self.NodeId}, AttributeId:{self.AttributeId}, IndexRange:{self.IndexRange}, Value:{self.Value})'

    __repr__ = __str__


class KeyValuePair(FrozenClass):
    """
    :ivar Key:
    :vartype Key: QualifiedName
    :ivar Value:
    :vartype Value: Variant
    """

    types = [
        ('Key', 'QualifiedName'),
        ('Value', 'Variant'),
    ]

    def __init__(self):
        self.Key = QualifiedName()
        self.Value = Variant()
        self._freeze = True

    def __str__(self):
        return 'KeyValuePair(Key:{self.Key}, Value:{self.Value})'

    __repr__ = __str__


class OpenSecureChannelResponse(FrozenClass):
    """
    :ivar TypeId:
    :vartype TypeId: NodeId
    :ivar ResponseHeader:
    :vartype ResponseHeader: ResponseHeader
    :ivar Parameters:
    :vartype Parameters: OpenSecureChannelResult
    """

    types = [
        ('TypeId', 'NodeId'),
        ('ResponseHeader', 'ResponseHeader'),
        ('Parameters', 'OpenSecureChannelResult'),
               ]

    def __init__(self):
        self.TypeId = FourByteNodeId(ObjectIds.OpenSecureChannelResponse_Encoding_DefaultBinary)
        self.ResponseHeader = ResponseHeader()
        self.Parameters = OpenSecureChannelResult()
        self._freeze = True

    def __str__(self):
        return 'OpenSecureChannelResponse(TypeId:{self.TypeId}, ResponseHeader:{self.ResponseHeader}, Parameters:{self.Parameters})'

    __repr__ = __str__


class OpenSecureChannelResult(FrozenClass):

    types = [
        ('ServerProtocolVersion', 'UInt32'),
        ('SecurityToken', 'ChannelSecurityToken'),
        ('ServerNonce', 'ByteString'),
               ]

    def __init__(self):
        self.ServerProtocolVersion = 0
        self.SecurityToken = ChannelSecurityToken()
        self.ServerNonce = None
        self._freeze = True

    def __str__(self):
        return 'OpenSecureChannelResult(ServerProtocolVersion:{self.ServerProtocolVersion}, SecurityToken:{' \
               'self.SecurityToken}, ServerNonce:{self.ServerNonce}) '

    __repr__ = __str__


class ChannelSecurityToken(FrozenClass):

    types = [
        ('ChannelId', 'UInt32'),
        ('TokenId', 'UInt32'),
        ('CreatedAt', 'DateTime'),
        ('RevisedLifetime', 'UInt32'),
               ]

    def __init__(self):
        self.ChannelId = 0
        self.TokenId = 0
        self.CreatedAt = datetime.datetime.utcnow()
        self.RevisedLifetime = 0
        self._freeze = True

    def __str__(self):
        return 'ChannelSecurityToken(ChannelId:{self.ChannelId}, TokenId:{self.TokenId}, CreatedAt:{self.CreatedAt}, ' \
               'RevisedLifetime:{self.RevisedLifetime}) '

    __repr__ = __str__


class SecurityTokenRequestType(IntEnum):
    Issue = 0
    Renew = 1


class ServiceFault(FrozenClass):

    types = [
        ('TypeId', 'NodeId'),
        ('ResponseHeader', 'ResponseHeader'),
               ]

    def __init__(self):
        self.TypeId = FourByteNodeId(ObjectIds.ServiceFault_Encoding_DefaultBinary)
        self.ResponseHeader = ResponseHeader()
        self._freeze = True

    def __str__(self):
        return 'ServiceFault(TypeId:{self.TypeId}, ResponseHeader:{self.ResponseHeader})'

    __repr__ = __str__



class RequestHeader(FrozenClass):
    """
    :ivar AuthenticationToken:
    :vartype AuthenticationToken: NodeId
    :ivar Timestamp:
    :vartype Timestamp: DateTime
    :ivar RequestHandle:
    :vartype RequestHandle: UInt32
    :ivar ReturnDiagnostics:
    :vartype ReturnDiagnostics: UInt32
    :ivar AuditEntryId:
    :vartype AuditEntryId: String
    :ivar TimeoutHint:
    :vartype TimeoutHint: UInt32
    :ivar AdditionalHeader:
    :vartype AdditionalHeader: ExtensionObject
    """

    ua_types = [
        ('AuthenticationToken', 'NodeId'),
        ('Timestamp', 'DateTime'),
        ('RequestHandle', 'UInt32'),
        ('ReturnDiagnostics', 'UInt32'),
        ('AuditEntryId', 'String'),
        ('TimeoutHint', 'UInt32'),
        ('AdditionalHeader', 'ExtensionObject'),
               ]

    def __init__(self):
        self.AuthenticationToken = NodeId()
        self.Timestamp = datetime.utcnow()
        self.RequestHandle = 0
        self.ReturnDiagnostics = 0
        self.AuditEntryId = None
        self.TimeoutHint = 0
        self.AdditionalHeader = ExtensionObject()
        self._freeze = True

    def __str__(self):
        return 'RequestHeader(AuthenticationToken:{self.AuthenticationToken}, Timestamp:{self.Timestamp}, RequestHandle:{self.RequestHandle}, ReturnDiagnostics:{self.ReturnDiagnostics}, AuditEntryId:{self.AuditEntryId}, TimeoutHint:{self.TimeoutHint}, AdditionalHeader:{self.AdditionalHeader})'

    __repr__ = __str__


class ResponseHeader(FrozenClass):

    types = [
        ('Timestamp', 'DateTime'),
        ('RequestHandle', 'UInt32'),
        ('ServiceResult', 'StatusCode'),
        ('ServiceDiagnostics', 'DiagnosticInfo'),
        ('StringTable', 'ListOfString'),
        ('AdditionalHeader', 'ExtensionObject'),
               ]

    def __init__(self):
        self.Timestamp = datetime.datetime.utcnow()
        self.RequestHandle = 0
        self.ServiceResult = StatusCode()
        self.ServiceDiagnostics = DiagnosticInfo()
        self.StringTable = []
        self.AdditionalHeader = ExtensionObject()
        self._freeze = True

    def __str__(self):
        return 'ResponseHeader(Timestamp:{self.Timestamp}, RequestHandle:{self.RequestHandle}, ServiceResult:{self.ServiceResult}, ServiceDiagnostics:{self.ServiceDiagnostics}, StringTable:{self.StringTable}, AdditionalHeader:{self.AdditionalHeader})'

    __repr__ = __str__



class SignatureData(FrozenClass):

    types = [
        ('Algorithm', 'String'),
        ('Signature', 'ByteString'),
               ]

    def __init__(self):
        self.Algorithm = None
        self.Signature = None
        self._freeze = True

    def __str__(self):
        return 'SignatureData(Algorithm:{self.Algorithm}, Signature:{self.Signature})'

    __repr__ = __str__



class CreateSessionResult(FrozenClass):

    types = [
        ('SessionId', 'NodeId'),
        ('AuthenticationToken', 'NodeId'),
        ('RevisedSessionTimeout', 'Double'),
        ('ServerNonce', 'ByteString'),
        ('ServerCertificate', 'ByteString'),
        ('ServerEndpoints', 'ListOfEndpointDescription'),
        ('ServerSoftwareCertificates', 'ListOfSignedSoftwareCertificate'),
        ('ServerSignature', 'SignatureData'),
        ('MaxRequestMessageSize', 'UInt32'),
               ]

    def __init__(self):
        self.SessionId = NodeId()
        self.AuthenticationToken = NodeId()
        self.RevisedSessionTimeout = 0
        self.ServerNonce = None
        self.ServerCertificate = None
        self.ServerEndpoints = []
        self.ServerSoftwareCertificates = []
        self.ServerSignature = SignatureData()
        self.MaxRequestMessageSize = 0
        self._freeze = True

    def __str__(self):
        return 'CreateSessionResult(SessionId:{self.SessionId}, AuthenticationToken:{self.AuthenticationToken}, RevisedSessionTimeout:{self.RevisedSessionTimeout}, ServerNonce:{self.ServerNonce}, ServerCertificate:{self.ServerCertificate}, ServerEndpoints:{self.ServerEndpoints}, ServerSoftwareCertificates:{self.ServerSoftwareCertificates}, ServerSignature:{self.ServerSignature}, MaxRequestMessageSize:{self.MaxRequestMessageSize})'

    __repr__ = __str__


class CreateSessionParameters(FrozenClass):

    types = [
        ('ClientDescription', 'ApplicationDescription'),
        ('ServerUri', 'String'),
        ('EndpointUrl', 'String'),
        ('SessionName', 'String'),
        ('ClientNonce', 'ByteString'),
        ('ClientCertificate', 'ByteString'),
        ('RequestedSessionTimeout', 'Double'),
        ('MaxResponseMessageSize', 'UInt32'),
               ]

    def __init__(self):
        self.ClientDescription = ApplicationDescription()
        self.ServerUri = None
        self.EndpointUrl = None
        self.SessionName = None
        self.ClientNonce = None
        self.ClientCertificate = None
        self.RequestedSessionTimeout = 0
        self.MaxResponseMessageSize = 0
        self._freeze = True

    def __str__(self):
        return 'CreateSessionParameters(ClientDescription:{self.ClientDescription}, ServerUri:{self.ServerUri}, EndpointUrl:{self.EndpointUrl}, SessionName:{self.SessionName}, ClientNonce:{self.ClientNonce}, ClientCertificate:{self.ClientCertificate}, RequestedSessionTimeout:{self.RequestedSessionTimeout}, MaxResponseMessageSize:{self.MaxResponseMessageSize})'

    __repr__ = __str__


class CreateSessionResponse(FrozenClass):

    types = [
        ('TypeId', 'NodeId'),
        ('ResponseHeader', 'ResponseHeader'),
        ('Parameters', 'CreateSessionResult'),
               ]

    def __init__(self):
        self.TypeId = FourByteNodeId(ObjectIds.CreateSessionResponse_Encoding_DefaultBinary)
        self.ResponseHeader = ResponseHeader()
        self.Parameters = CreateSessionResult()
        self._freeze = True

    def __str__(self):
        return 'CreateSessionResponse(TypeId:{self.TypeId}, ResponseHeader:{self.ResponseHeader}, Parameters:{self.Parameters})'

    __repr__ = __str__



class DiagnosticInfo(FrozenClass):

    switches = {
        'SymbolicId': ('Encoding', 0),
        'NamespaceURI': ('Encoding', 1),
        'Locale': ('Encoding', 3),
        'LocalizedText': ('Encoding', 2),
        'AdditionalInfo': ('Encoding', 4),
        'InnerStatusCode': ('Encoding', 5),
        'InnerDiagnosticInfo': ('Encoding', 6),
               }
    types = [
        ('Encoding', 'Byte'),
        ('SymbolicId', 'Int32'),
        ('NamespaceURI', 'Int32'),
        ('Locale', 'Int32'),
        ('LocalizedText', 'Int32'),
        ('AdditionalInfo', 'String'),
        ('InnerStatusCode', 'StatusCode'),
        ('InnerDiagnosticInfo', 'DiagnosticInfo'),
               ]

    def __init__(self):
        self.Encoding = 0
        self.SymbolicId = None
        self.NamespaceURI = None
        self.Locale = None
        self.LocalizedText = None
        self.AdditionalInfo = None
        self.InnerStatusCode = None
        self.InnerDiagnosticInfo = None
        self._freeze = True

    def __str__(self):
        return 'DiagnosticInfo(Encoding:{self.Encoding}, SymbolicId:{self.SymbolicId}, NamespaceURI:{' \
               'self.NamespaceURI}, Locale:{self.Locale}, LocalizedText:{self.LocalizedText}, AdditionalInfo:{' \
               'self.AdditionalInfo}, InnerStatusCode:{self.InnerStatusCode}, InnerDiagnosticInfo:{' \
               'self.InnerDiagnosticInfo}) '

    __repr__ = __str__


class GenericAttributeValue(FrozenClass):
    """
    :ivar AttributeId:
    :vartype AttributeId: UInt32
    :ivar Value:
    :vartype Value: Variant
    """

    ua_types = [
        ('AttributeId', 'UInt32'),
        ('Value', 'Variant'),
    ]

    def __init__(self):
        self.AttributeId = 0
        self.Value = Variant()
        self._freeze = True

    def __str__(self):
        return 'GenericAttributeValue(AttributeId:{self.AttributeId}, Value:{self.Value})'

    __repr__ = __str__


class EnumValueType(FrozenClass):
    """
    :ivar Value:
    :vartype Value: Int64
    :ivar DisplayName:
    :vartype DisplayName: LocalizedText
    :ivar Description:
    :vartype Description: LocalizedText
    """

    types = [
        ('Value', 'Int64'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
    ]

    def __init__(self):
        self.Value = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self._freeze = True

    def __str__(self):
        return 'EnumValueType(Value:{self.Value}, DisplayName:{self.DisplayName}, Description:{self.Description})'

    __repr__ = __str__


class Argument(FrozenClass):
    """
    :ivar Name:
    :vartype Name: String
    :ivar DataType:
    :vartype DataType: NodeId
    :ivar ValueRank:
    :vartype ValueRank: Int32
    :ivar ArrayDimensions:
    :vartype ArrayDimensions: UInt32
    :ivar Description:
    :vartype Description: LocalizedText
    """

    types = [
        ('Name', 'String'),
        ('DataType', 'NodeId'),
        ('ValueRank', 'Int32'),
        ('ArrayDimensions', 'ListOfUInt32'),
        ('Description', 'LocalizedText'),
    ]

    def __init__(self):
        self.Name = None
        self.DataType = NodeId()
        self.ValueRank = 0
        self.ArrayDimensions = []
        self.Description = LocalizedText()
        self._freeze = True

    def __str__(self):
        return 'Argument(Name:{self.Name}, DataType:{self.DataType}, ValueRank:{self.ValueRank}, ArrayDimensions:{self.ArrayDimensions}, Description:{self.Description})'

    __repr__ = __str__


class MethodAttributes(FrozenClass):

    types = [
        ('SpecifiedAttributes', 'UInt32'),
        ('DisplayName', 'LocalizedText'),
        ('Description', 'LocalizedText'),
        ('WriteMask', 'UInt32'),
        ('UserWriteMask', 'UInt32'),
        ('Executable', 'Boolean'),
        ('UserExecutable', 'Boolean'),
    ]

    def __init__(self):
        self.SpecifiedAttributes = 0
        self.DisplayName = LocalizedText()
        self.Description = LocalizedText()
        self.WriteMask = 0
        self.UserWriteMask = 0
        self.Executable = True
        self.UserExecutable = True
        self._freeze = True

    def __str__(self):
        return 'MethodAttributes(SpecifiedAttributes:{self.SpecifiedAttributes}, DisplayName:{self.DisplayName}, Description:{self.Description}, WriteMask:{self.WriteMask}, UserWriteMask:{self.UserWriteMask}, Executable:{self.Executable}, UserExecutable:{self.UserExecutable})'

    __repr__ = __str__


extension_object_classes = {}
extension_object_ids = {}


class BrowseNextParameters(FrozenClass):

    types = [
        ('ReleaseContinuationPoints', 'Boolean'),
        ('ContinuationPoints', 'ListOfByteString'),
               ]

    def __init__(self):
        self.ReleaseContinuationPoints = True
        self.ContinuationPoints = []
        self._freeze = True

    def __str__(self):
        return 'BrowseNextParameters(ReleaseContinuationPoints:{self.ReleaseContinuationPoints}, ContinuationPoints:{self.ContinuationPoints})'

    __repr__ = __str__


class BrowseDescription(FrozenClass):

    types = [
        ('NodeId', 'NodeId'),
        ('BrowseDirection', 'BrowseDirection'),
        ('ReferenceTypeId', 'NodeId'),
        ('IncludeSubtypes', 'Boolean'),
        ('NodeClassMask', 'UInt32'),
        ('ResultMask', 'UInt32'),
               ]

    def __init__(self):
        self.NodeId = NodeId()
        self.BrowseDirection = BrowseDirection(0)
        self.ReferenceTypeId = NodeId()
        self.IncludeSubtypes = True
        self.NodeClassMask = 0
        self.ResultMask = 0
        self._freeze = True

    def __str__(self):
        return 'BrowseDescription(NodeId:{self.NodeId}, BrowseDirection:{self.BrowseDirection}, ReferenceTypeId:{self.ReferenceTypeId}, IncludeSubtypes:{self.IncludeSubtypes}, NodeClassMask:{self.NodeClassMask}, ResultMask:{self.ResultMask})'

    __repr__ = __str__


class BrowseParameters(FrozenClass):

    types = [
        ('View', 'ViewDescription'),
        ('RequestedMaxReferencesPerNode', 'UInt32'),
        ('NodesToBrowse', 'ListOfBrowseDescription'),
               ]

    def __init__(self):
        self.View = ViewDescription()
        self.RequestedMaxReferencesPerNode = 0
        self.NodesToBrowse = []
        self._freeze = True

    def __str__(self):
        return 'BrowseParameters(View:{self.View}, RequestedMaxReferencesPerNode:{self.RequestedMaxReferencesPerNode}, NodesToBrowse:{self.NodesToBrowse})'

    __repr__ = __str__


class BrowseResult(FrozenClass):

    types = [
        ('StatusCode', 'StatusCode'),
        ('ContinuationPoint', 'ByteString'),
        ('References', 'ListOfReferenceDescription'),
               ]

    def __init__(self):
        self.StatusCode = StatusCode()
        self.ContinuationPoint = None
        self.References = []
        self._freeze = True

    def __str__(self):
        return 'BrowseResult(StatusCode:{self.StatusCode}, ContinuationPoint:{self.ContinuationPoint}, References:{self.References})'

    __repr__ = __str__


class ViewDescription(FrozenClass):

    types = [
        ('ViewId', 'NodeId'),
        ('Timestamp', 'DateTime'),
        ('ViewVersion', 'UInt32'),
               ]

    def __init__(self):
        self.ViewId = NodeId()
        self.Timestamp = datetime.datetime.utcnow()
        self.ViewVersion = 0
        self._freeze = True

    def __str__(self):
        return 'ViewDescription(ViewId:{self.ViewId}, Timestamp:{self.Timestamp}, ViewVersion:{self.ViewVersion})'

    __repr__ = __str__


# nid = FourByteNodeId(ObjectIds.NodeAttributes_Encoding_DefaultBinary)
# extension_object_classes[nid] = NodeAttributes
# extension_object_ids['NodeAttributes'] = nid
# nid = FourByteNodeId(ObjectIds.WriteValue_Encoding_DefaultBinary)
# extension_object_classes[nid] = WriteValue
# extension_object_ids['WriteValue'] = nid
# nid = FourByteNodeId(ObjectIds.EnumValueType_Encoding_DefaultBinary)
# extension_object_classes[nid] = EnumValueType
# extension_object_ids['EnumValueType'] = nid
# nid = FourByteNodeId(ObjectIds.VariableAttributes_Encoding_DefaultBinary)
# extension_object_classes[nid] = VariableAttributes
# extension_object_ids['VariableAttributes'] = nid
# nid = FourByteNodeId(ObjectIds.GenericAttributeValue_Encoding_DefaultBinary)
# extension_object_classes[nid] = GenericAttributeValue
# extension_object_ids['GenericAttributeValue'] = nid
# nid = FourByteNodeId(ObjectIds.GenericAttributes_Encoding_DefaultBinary)
# extension_object_classes[nid] = GenericAttributes
# extension_object_ids['GenericAttributes'] = nid
# nid = FourByteNodeId(ObjectIds.ServerStatusDataType_Encoding_DefaultBinary)
# extension_object_classes[nid] = ServerStatusDataType
# extension_object_ids['ServerStatusDataType'] = nid
