import logging
import os
from datetime import datetime, timedelta, timezone

from base import BaseModel


"""
location_address.(location)
location_region.(location)
location_point.(location)

it_asset.(asset)
data.(asset)
organization.(asset)
person.(asset)
circuit.(it_asset)
computing_device.(it_asset)
database.(it_asset)
network.(it_asset)
service.(it_asset)
software.(it_asset)
system.(it_asset)
website.(it_asset)
"""

# Custom Data types
'''
CidrType:
    name: cidr-type
    type: String
    serializable
    pattern: ([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))/([0-9]|[1-2][0-9]|3[0-2])
    Notes: use python library ipaddress for this.

CpeType:
    name: CpeType
    type: String
    serializable
    name: cpe-type
    memberTypes:
        name: Cpe23Type
            url: http://cpe.mitre.org/naming/2.0#cpe23Type
            type: String
            DocString: Define the format for acceptable CPE Names. A string format is used with
                the id starting with the word cpe:2.3 followed by : and then some number of individual components
                separated by colons.
            pattern: cpe:2\.3:[aho\*\-](:(((\?*|\*?)([a-zA-Z0-9\-\._]|(\\[\\\*\?!"#$$%25&'\(\)\+,/:;<=>@\[\]\^`\{\|}~]))+(\?*|\*?))|[\*\-])){5}(:(([a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?)|[\*\-]))(:(((\?*|\*?)([a-zA-Z0-9\-\._]|(\\[\\\*\?!"#$$%25&'\(\)\+,/:;<=>@\[\]\^`\{\|}~]))+(\?*|\*?))|[\*\-])){4}

        name: Cpe22Type
            url: http://cpe.mitre.org/naming/2.0#cpe22Type
            type: String
            DocString: Define the format for acceptable CPE Names. A URN format is used with the
                id starting with the word cpe followed by :/ and then some number of individual components separated by
                colons.
            pattern: [cC][pP][eE]:/[AHOaho]?(:[A-Za-z0-9\._\-~%25]*){0,6}


    Notes: Common Platform Enumeration now being ran by NIST


HostnameType:
        name: HostnameType
        type: String
        serializable
        name: hostname-type
        baseType: token http://www.eclipse.org/emf/2003/XMLType#token
        pattern: [\w\-]+(\.[\w\-]+){0,}

Ipv4Type:
        name: Ipv4Type
        type: String
        serializable
        name: ipv4-type
        baseType: Token
        pattern: ([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))\.([0-9]|[1-9][0-9]|1([0-9][0-9])|2([0-4][0-9]|5[0-5]))

Ipv6Type
        name: Ipv6Type
        type: String
        serializable
        name: ipv6-type
        baseType: Token
        pattern: ([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}

LatitudeType
        name: LatitudeType
        type: double
        serializable
        name: latitude_._type
        minInclusive: -90
        maxInclusive: 90

LatitudeTypeObject
        name: LatitudeTypeObject
        type: double
        serializable
        name: latitude_._type:Object
        baseType: latitude_._type

LongitudeType
        name: LongitudeType
        type: double
        serializable
        name: longitude_._type
        minExclusive: -180
        maxInclusive: 180

LongitudeTypeObject
        name: LongitudeTypeObject
        type: double
        serializable
        name: longitude_._type:Object
        baseType: longitude_._type

LocaleType:
        name: LocaleType
        type: String
        serializable
        name: locale-type
        baseType: Token
        pattern: [a-zA-Z]{2,3}(-([a-zA-Z]{2}|[0-9]{3}))?

MacAddressType
        name: MacAddressType
        type: String
        serializable
        name: mac-address-type
        baseType: Token
        pattern: ([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}

PortType
        name: PortType
        type: BigInteger
        serializable
        name: port-type
        baseType: http://www.eclipse.org/emf/2003/XMLType#integer
        minInclusive: 0
        maxInclusive: 65535

RadiusType
        name: RadiusType
        type: double
        serializable
        name: radius_._type
        minInclusive: 0

RadiusTypeObject
        name: RadiusTypeObject
        type: double
        serializable
        name: radius_._type:Object
        baseType: radius_._type

TelephoneNumberType
        name: TelephoneNumberType
        type: String
        serializable
        name: telephone-number-type
        pattern: (([2-9][0-8]\d-[2-9]\d{2}-[0-9]{4})|(\+([0-9]%20?){6,14}[0-9]))

'''


class AssetIdentificationType(object):
    '''
        class:
            name: asset-identification-type
            kind: elementOnly
            Super Types: AssetsType -> RelationshipsContainerType

        Attribute:
            Name: assetRef
            Lower bound = 1
            Upper bound = 1
            ordered, unique, changeable
            Type: String
    '''
    pass


class AssetsType(object):
    '''
        class:
            name: assets-type
            kind: elementOnly
            Super Types: RelationshipsContainerType
        Reference:
            name: asset
            Lower bound = 1
            upper bound = *
            Containment, ordered, unique, changeable
            Type: AssetType _obj
            Kind: element
            namespace: ##targetNamespace
    '''
    pass


class AssetType(object):
    '''
        class:
            name: asset_._type
            kind: elementOnly
        Attribute:
            name: assetGroup
            Lower bound = 1
            Upper bound = 1
            ordered, unique, changeable
            DocString: Holds identifying attributes that are common to all assets.
            Type: FeatureMapEntry??
            Kind: group (list?)
            namespace: ##targetNamespace
        Reference:
            name: asset
            Lower = 1
            Upper = 1
            Containment, transient, derived, ordered, unique, volatile
            DocString: Holds identifying attributes that are common to all assets.
            kind: element
            namespace: ##targetNamespace
            group: assetGroup
            type: AssetType1
        Attribute:
            name: id
            type: NCName | String
            Lower = 1
            Upper = 1
            ordered, unique, changeable
            DocString: An internal ID to identify this asset.
            kind: Attribute
        Attribute:
            name: anyAttribute
            type: FeatureMapEntry
            Lower = 0
            Upper = *
            ordered, changeable
            DocString: A placeholder so that content creators can add attributes as desired.
            kind: attributeWildcard
            wildcards: ##other
            processing: strict
    '''
    pass


class AssetType1(object):
    '''
        class:
            name: AssetType1
            Abstract (weather instances of this class can be created)
            name: asset-type
            kind: elementOnly
        Reference:
            name: syntheticId
            type: SyntheticIdType
            Lower = 0
            Upper = *
            Containment, ordered, unique, changeable
            DocString: Holds the synthetic ID for the asset
            kind: element
            name: synthetic-id
            namespace: ##targetNamespace
        Reference:
            name: locations
            type: LocationsType
            lower = 0
            Upper = 1
            Containment, ordered, unique, changeable
            DocString: One or more locations where this asset resides
            kind: element
            name: locations
            namespace: ##targetNamespace
        Reference:
            name: extendedInformation
            type: ExtendedInformationType
            lower = 0
            uppoer = 1
            Containment, ordered, unique, changeable
            DocString: This is a container to hold any addtional identifying information for an asset, as specified by the content creator.
            kind: element
            name: extended-information
            namespace: ##targetNamespace
        Attribute:
            name: timestamp
            type: datetime.now(tz=timezone.utc)
            lower = 0
            uppoer = 1
            ordered, unique, changeable
            DocString: Indicates when the data was last known to be correct.
            kind: attribute
            name: timestamp
            namespace: ##targetNamespace
    '''
    pass


class ExtendedInformationType(object):
    '''
        class:
            name: ExtendedInformationType
            kind: elementOnly
        Attribute:
            name: any
            type: featureMapEntry
            lower 1
            upper *
            kind: elementWildcard
            wildcards: ##other
            processing: lax
    '''
    pass


class BirthdateType(object):
    '''
        class:
            name: BirthdateType
            name: birthdate_._type
            kind: simple
        Attribute:
            name: value
            type: Date
            lower = 0
            uppoer = 1
            ordered, unique, changeable
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            ordered, unique, changeable
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
            namespace: ##targetNamespace
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for date.
            # TODO: convert to datetime object.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class CidrType1(object):
    '''
        class:
            name: CidrType1
            kind: simple
        Attribute:
            name: value
            Type: CidrType
            lower = 0
            uppoer = 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            uppoer = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            Attribute: timestamp
            Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for CidrType
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class CircuitNameType(object):
    '''
        class:
            name: CircuitNameType
            kind: simple
        Attribute:
            name: value
            Type: Token (String)
            lower = 0
            uppoer = 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            uppoer = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            Attribute: timestamp
            Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class CircuitType(object):
    '''
        class:
            name: CircuitType
            Super Type: itAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: circuitName
            Type: CircuitNameType
            lower = 0
            uppoer = 1
            DocString: The common name for the circult.
            kind: element
    '''
    pass


class ComputingDeviceType(object):
    '''
        class:
            name: ComputingDeviceType
            Super Types: itAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: distinguishedName
            type: DistinguishedNameType
            lower = 0
            upper = 1
            DocString: The full X.500 distinguished name for the device.
            kind: element
        Reference:
            name: cpe
            type: CpeType1
            lower = 0
            uppoer = *
            DocString: The hardware CPE name for the device (CPE 2.2 URI or CPE 2.3 Formatted String).
            kind: element
        Reference:
            name: connections
            type: ConnectionsType
            lower 0
            uppoer 1
            DocString: The IP network interface connections that exist for the device (regardless
                                of if the network interface is connected to a network or not).
            kind: element
        Reference:
            name: fqdn
            Type: FqdnType
            lower 0
            upper 1
            DocString: The fully qualified domain name for the object.
            kind: element
        Reference:
            name: hostname
            type: HostnameType1
            lower 0
            upper 1
            DocString: The hostname of the computing device.
            kind: element
        Reference:
            name: motherboardGuid
            type: MotherboardGuidType
            lower 0
            upper 1
            DocString: The motherboard globally unique identifier of the computing device.
            kind: element
    '''
    pass


class ConnectionsType(object):
    '''
        class:
            name: ConnectionsType
            kind: elementOnly
        Reference:
            name: connection
            type: NetworkInterfaceType
            lower: 1
            upper *
            DocString: An IP network interface connection.
            kind: element
    '''
    pass


class CpeType1(object):
    '''
        class:
            name: CpeType1
            kind: simple
        Attribute:
            name: value
            type: CpeType
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for CpeType
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class DatabaseType(object):
    '''
        class:
            name: DatabaseType
            Super Types: itAssetType -> AssetType1
            kind elementOnly
        Reference:
            name: instanceName
            type: InstanceNameType
            lower 0
            upper 1
            DocString: The name of the database instance being identified.
            kind: element
    '''
    pass


class DataType(object):
    '''
        class:
            name: DataType
            Suepr Types: AssetType1
            kind: elementOnly
    '''
    pass


class DistinguishedNameType(object):
    '''
        class:
            name: DistinguishedNameType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class EmailAddressType(object):
    '''
        class:
            name: EmailAddressType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class FqdnType(object):
    '''
        class:
            name: FqdnType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class HostnameType1(object):
    '''
        class:
            name: HostnameType1
            kind: simple
        Attribute:
            name: value
            type: HostnameType (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for HostnameType
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class HostType(object):
    '''
        class:
            name: HostType
            kind: elementOnly
        Reference:
            name: fqdn
            type: FqdnType
            lower 0
            upper 1
            DocString: The fully qualified domain name for the object.
            kind: element
        Reference:
            name: ipAddress
            type: IpAddressType
            lower 0
            upper 1
            DocString: An IP address
            kind: element
    '''
    pass


class InstallationIdType(object):
    '''
        class:
            name: InstallationIdType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class InstanceNameType(object):
    '''
        class:
            name: InstanceNameType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class IpAddressType(object):
    '''
        class:
            name: IpAddressType
            kind: elementOnly
        Reference:
            name: ipV4
            type: IpV4Type1
            lower 0
            upper 1
            kind: element
        Reference:
            name: ipV6
            type: IpV6Type1
            kind: element
    '''
    pass


class IpNetRangeType(object):
    '''
        class:
            name: IpNetRangeType
            kind: elementOnly
        Reference:
            name: ipNetRangeStart
            type: IpAddressType
            lower 1
            upper 1
            DocString: The starting IP address in the network.
            kind: element
        Reference:
            name: ipNetRangeEnd
            type: IpAddressType
            lower 1
            upper 1
            DocString: The ending IP address in the network.
            kind: element
    '''
    pass


class IpV4Type1(object):
    '''
        class:
            name: IpV4Type1
            kind: simple
        Attribute:
            name: value
            type: Ipv4Type (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for IpV4Type
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class IpV6Type1(object):
    '''
        class:
            name: IpV6Type1
            kind: simple
        Attribute:
            name: value
            type: Ipv6Type (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for ipv6 type
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class ItAssetType(object):
    '''
        class:
            name: ItAssetType
            Super Type: AssetType1
            kind: elementOnly
    '''
    pass


class LicenseType(object):
    '''
        class:
            name: LicenseType
            kind: simple
        Attribute:
            name: value
            type: (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class LocaleType1(object):
    '''
        class:
            name: LocaleType1
            kind: simple
        Attribute:
            name: value
            type: LocaleType (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for LocaleType
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class LocationPointType(object):
    '''
        class:
            name: LocationPointType
            kind: empty
        Attribute:
            name: elevation
            type: double
            lower 0
            upper 1
            DocString: The elevation of the asset, specified in meters from sea level.
            kind: attribute
        Attribute:
            name: latitude
            type: LatitudeType
            lower 1
            upper 1
            DocString: The latitude of the asset, defined between -90 (90 degrees South, inclusive) and 90 (90 degrees North, inclusive).
            kind: attribute
        Attribute:
            name: longitude
            type: LongitudeType
            lower 1
            upper 1
            DocString: The longitude of the asset, defined between -180 (180 degrees West, exclusive) and 180 (180 degrees East, inclusive).
            kind: attribute
        Attribute:
            name: radius
            type: RadiusType
            lower 0
            upper 1
            DocString: The radius of a horizontal circle centered on the point within which the asset resides.
            kind: attribute
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''
    pass


class LocationRegionType(object):
    '''
        class:
            name: LocationRegionType
            kind: simple
        Attribute:
            name: value
            type: NormalizedString (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for NormalizedString
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class LocationsType(object):
    '''
        class:
            name: LocationsType
            kind: elementOnly
        Attribute:
            name: locationGroup
            type: FeatureMapEntry
            lower 0
            upper *
            DocString: The base for a subtitution group for elements that contain location information.
            kind: group
            name: location:group
        Reference:
            name: location
            type: EObject [org.eclipse.emf.ecore.EObject]
            lower 1
            upper *
            DocString: The base for a subtitution group for elements that contain location information.
            kind: element
            group: location:group

    '''
    pass


class MacAddressType1(object):
    '''
        class:
            name: MacAddressType1
            kind: simple
        Attribute:
            name: value
            type: MacAddressType (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for MacAddressType
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class MotherboardGuidType(object):
    '''
        class:
            name: MotherboardGuidType
            kind: simple
        Attribute:
            name: value
            type: String (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class NetworkInterfaceType(object):
    '''
        class:
            name: NetworkInterfaceType
            kind: elementOnly
        Reference:
            name: ipAddress
            type: IpAddressType
            lower 0
            upper 1
            DocString: The IP address for this network interface.
            kind: element
        Reference:
            name: macAddress
            type: MacAddressType1
            lower 0
            upper 1
            DocString: The MAC address associated with this network interface.
        Reference:
            name: url
            type: UrlType
            lower 0
            upper 1
            DocString: A URL in a relevant DNS server for this IP address.
            kind: element
        Reference:
            name: subnetMask
            type: IpAddressType
            lower 0
            upper 1
            DocString: The subnet mask address for this network interface.
            kind: element
        Reference:
            name: defaultRoute
            type: IpAddressType
            lower 0
            upper 1
            DocString: The IP address for the default gateway of this connection.
            kind: element
    '''
    pass


class NetworkNameType(object):
    '''
        class:
            name: NetworkNameType
            kind: simple
        Attribute:
            name: value
            type: NormalizedString (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: Add validation for NormalizedString.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class NetworkType(object):
    '''
        class:
            name: NetworkType
            Super Types: ItAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: networkName
            type: NetworkNameType
            lower 0
            upper 1
            DocString: The name of the network as commonly referred to.
            kind: element
        Reference:
            name: ipNetRange
            type: IpNetRangeType
            lower 0
            upper 1
            DocString: The start and end IP addresses to indicate the range of IP addresses covered by this network.
            kind: element
        Reference:
            name: cidr
            type: CidrType1
            lower 0
            upper 1
            DocString: The classless inter-domain routing notation for the network.
            kind: element
    '''
    pass


class OrganizationType(object):
    '''
        class:
            name: OrganizationType
            Super Types: AssetType1
            kind: elementOnly
        Reference:
            name: organisationNameDetails
            type: OrganisationNameDetailsType -> OrganisationNameDetails
            lower 0
            upper *
            DocString: A container for organisation name details.
            kind: element
            namespace: urn:oasis:names:tc:ciq:xsdschema:xNL:2.0
        Reference:
            name: emailAddress
            type: EmailAddressType
            lower 0
            upper *
            DocString: An email address
            kind: element
        Reference:
            name: telephoneNumber
            type: TelephoneNumberType1
            lower 0
            upper *
            DocString: The telephone number. For a North American number, the number must be valid and the format
                must be XXX-XXX-XXXX where X is a digit. For an international number, the number must begin with a '+'
                symbol, followed by 7 to 15 digits. A space may be used between digits, as appropriate. For example: +88
                888 888 8 (this is following the ITU-T E.123 notation).
            kind: element
        Reference:
            name: websiteUrl
            type: WebsiteUrlType
            lower 0
            upper *
            DocString: The URL to the website.
            kind: element
    '''
    pass


class PersonType(object):
    '''
        class:
            name: PersonType
            Super Types: AssetType1
            kind: elementOnly
        Reference:
            name: personName
            type: PersonNameType -> PersonName
            lower 0
            upper 1
            DocString: Container for person name details.
            kind: element
            namespace: urn:oasis:names:tc:ciq:xsdschema:xNL:2.0
        Reference:
            name: emailAddress
            type: EmailAddressType
            lower 0
            upper *
            DocString: An email address
            kind: element
        Reference:
            name: telephoneNumber
            type: TelephoneNumberType1
            lower 0
            upper *
            DocString: The telephone number. For a North American number, the number must be valid and the format
                must be XXX-XXX-XXXX where X is a digit. For an international number, the number must begin with a '+'
                symbol, followed by 7 to 15 digits. A space may be used between digits, as appropriate. For example: +88
                888 888 8 (this is following the ITU-T E.123 notation).
            kind: element
        Reference:
            name: birthdate
            type: BirthdateType
            lower 0
            upper 1
            DocString: The birthdate of the person.
            kind: element
    '''
    pass


class PortRangeType(object):
    '''
        class:
            name: PortRangeType
            kind: empty
        Attribute:
            name: lowerBound
            type: PortType (BigInteger)
            lower 1
            upper 1
            kind: attribute
        Attribute:
            name: upperBound
            type: PortType (BigInteger)
            lower 1
            upper 1
            kind: attribute
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''
    pass


class PortType1(object):
    '''
        class:
            name: PortType1
            kind: simple
        Attribute:
            name: value
            type: PortType (BigInteger)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise
        except:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = int

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            if val <= 0 and val <= 65535:
                return val
            else:
                raise ValueError(
                    "Expected int between 0 and 65535, received {}".format(val))
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class ProtocolType(object):
    '''
        class:
            name: ProtocolType
            kind: simple
        Attribute:
            name: value
            type: String
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class ServiceType(object):
    '''
        class:
            name: ServiceType
            Super Types: ItAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: host
            type: HostType
            lower 0
            upper 1
            DocString: The hostname or IP address where the service is hosted.
            kind: element
        Reference:
            name: port
            type: PortType1
            lower 0
            upper *
            DocString: The port to which the service is bound.
            kind: element
        Reference:
            name: portRange
            type: PortRangeType
            lower 0
            upper *
            DocString: The inclusive port range to which the service is bound.
            kind: element
        Reference:
            name: protocol
            type: ProtocolType
            lower 0
            upper 1
            DocString: The protocol used to interact with the service.
            kind: element
    '''
    pass


class SoftwareType(object):
    '''
        class:
            name: SoftwareType
            Super Types: ItAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: installationId
            type: InstallationIdType
            lower 0
            upper 1
            DocString: Any identifier for the software instance (installation)
            kind: element
        Reference:
            name: cpe
            type: CpeType1
            lower 0
            upper 1
            DocString: The CPE name for the software (CPE 2.2 URI or CPE 2.3 Formatted String).
            kind: element
        Reference:
            name: license
            type: LicenseType
            lower 0
            upper *
            DocString: The license key for the software.
            kind: element
    '''
    pass


class SyntheticIdType(object):
    '''
        class:
            name: SyntheticIdType
            kind: empty
        Attribute:
            name: id
            type: Token
            lower 1
            upper 1
            DocString: The ID of the asset within the resource namespace.
            kind: attribute
        Attribute:
            name: resource
            type: AnyURI [java.lang.String]
            lower 1
            upper 1
            DocString: The namespace governing this synthetic ID.
            kind: attribute
    '''
    pass


class SystemNameType(object):
    '''
        class:
            name: SystemNameType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class SystemType(object):
    '''
        class:
            name: SystemType
            Super types: ItAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: systemName
            type: SystemNameType
            lower 0
            upper *
            DocString: The name of the system. It is possible that a system have multiple names, or even abbreviated names.
                        Each one of those names may be captured here.
            kind: element
        Reference:
            name: version
            type: VersionType
            lower 0
            upper 1
            DocString: The version of the system.
            kind: element
    '''
    pass


class TelephoneNumberType1(object):
    '''
        class:
            name: TelephoneNumberType1
            kind: simple
        Attribute:
            name: value
            type: TelephoneNumberType (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            # TODO: add validation for phone number
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class UrlType(object):
    '''
        class:
            name: UrlType
            kind: simple
        Attribute:
            name: value
            type: AnyURI (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class VersionType(object):
    '''
        class:
            name: VersionType
            kind: simple
        Attribute:
            name: value
            type: Token (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class WebsiteType(ItAssetType):
    '''
        class:
            name: WebsiteType
            Super Types: ItAssetType -> AssetType1
            kind: elementOnly
        Reference:
            name: documentRoot??
            type: DocumentRootType??
            lower 0
            upper 1
            DocString: The absolute path to the document root location of the website on the host.
            kind: element
        Reference:
            name: locale
            type: LocaleType1
            lower 0
            uppoer 1
            DocString: The locale of the website represented as an RFC 5646 language, and optionally, region code.
            kind: element
    '''
    pass


class WebsiteUrlType(object):
    '''
        class:
            name: WebsiteUrlType
            kind: simple
        Attribute:
            name: value
            type: AnyURI (String)
            lower 0
            upper 1
            kind: simple
        Attribute:
            name: source
            type: String
            lower = 0
            upper = 1
            DocString: Contains the source of the information. The value of this field is left open to the
                content producer, but MAY include a synthetic ID of the asset which sourced the information, another ID
                of the source, or a description of the source.
            kind: attribute
            name: source
        Attribute: timestamp
        Attribute: anyAttribute (list of AnyAttribute() objects)
    '''

    def __init__(self, attributes=None):
        self._value = ''
        self._source = ''
        self.timestamp = None
        self.attributes = attributes

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise

        self._timestamp()

    @property
    def source(self):
        return self._source

    @source.setter
    def source(self, src):
        try:
            self._source = self._source_validate(src)
        except TypeError:
            raise

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''
        TYPE = str

        if isinstance(val, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))

    def _source_validate(self, src):
        ''' Internal function to validate source attribute. '''
        TYPE = str

        if isinstance(src, TYPE):
            return src
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(src).__name__))


class AnyAttribute(object):
    '''A placeholder so that content creators can add attributes as desired.
        Args:
            name: (str) Name of attribute.
            value: (str, dict, list, tuple) Value can be any built-in data type.

    '''

    def __init__(self, name, value, source):
        self._name = name
        self._value = value
        self._value_type = None

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, n):
        try:
            self._name = self._name_validate(n)
        except TypeError:
            raise

    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, val):
        try:
            self._set_value_type(val)
        except:
            raise

        try:
            self._value = self._value_validate(val)
        except TypeError:
            raise
        except:
            raise

        self._timestamp()

    def _set_value_type(val):
        '''Verifies value is builtin data type and sets value type.'''
        if isinstance(val, (str, list, dict, int, tuple, bool)):
            self._value_type = type(val)
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(n).__name__))

    def _timestamp(self):
        ''' Internal function to update timestamp when value is set. '''
        self.timestamp = datetime.now(timezone.utc)

    def _name_validate(self, n):
        ''' Internal function to validate name attribute. '''

        TYPE = str

        if isinstance(n, TYPE):
            # Other validation here if needed. Raise exceptions as needed.
            return n
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(n).__name__))

    def _value_validate(self, val):
        ''' Internal function to validate value attribute. '''

        if isinstance(val, self._value_type):
            return val
        else:
            raise TypeError("Expected '{}' but received a '{}'".format(
                TYPE.__name__, type(val).__name__))


'''
class location(BaseModel):

class locationAddress(location):

class locationPoint(location):




class asset(BaseModel):

class itAsset(asset):

class data(asset):

class organization(asset):

class person(asset):

class circuit(itAsset):

class computingDevice(itAsset):

class database(itAsset):

class network(itAsset):

class service(itAsset):

class software(itAsset):

class system(itAsset):

class website(itAsset):
'''
