#!/usr/bin/env python

import re

from ..debugging import bacpypes_debugging, ModuleLogger

from ..task import OneShotTask
from ..primitivedata import Atomic, Null, BitString, CharacterString, \
    Date, Integer, Double, Enumerated, OctetString, Real, Time, Unsigned
from ..basetypes import PropertyIdentifier, DateTime, NameValue, BinaryPV, \
    ChannelValue, DoorValue, PriorityValue, PriorityArray
from ..constructeddata import Array, ArrayOf, SequenceOf

from ..errors import ExecutionError
from ..object import Property, ReadableProperty, WritableProperty, OptionalProperty, Object, \
    AccessDoorObject, AnalogOutputObject, AnalogValueObject, \
    BinaryOutputObject, BinaryValueObject, BitStringValueObject, CharacterStringValueObject, \
    DateValueObject, DatePatternValueObject, DateTimePatternValueObject, \
    DateTimeValueObject, IntegerValueObject, \
    LargeAnalogValueObject, LightingOutputObject, MultiStateOutputObject, \
    MultiStateValueObject, OctetStringValueObject, PositiveIntegerValueObject, \
    TimeValueObject, TimePatternValueObject, ChannelObject


# some debugging
_debug = 0
_log = ModuleLogger(globals())

# handy reference
ArrayOfPropertyIdentifier = ArrayOf(PropertyIdentifier)

#
#   CurrentPropertyList
#

@bacpypes_debugging
class CurrentPropertyList(Property):

    def __init__(self):
        if _debug: CurrentPropertyList._debug("__init__")
        Property.__init__(self, 'propertyList', ArrayOfPropertyIdentifier, default=None, optional=True, mutable=False)

    def ReadProperty(self, obj, arrayIndex=None):
        if _debug: CurrentPropertyList._debug("ReadProperty %r %r", obj, arrayIndex)

        # make a list of the properties that have values
        property_list = [k for k, v in obj._values.items()
            if v is not None
                and k not in ('objectName', 'objectType', 'objectIdentifier', 'propertyList')
            ]
        if _debug: CurrentPropertyList._debug("    - property_list: %r", property_list)

        # sort the list so it's stable
        property_list.sort()

        # asking for the whole thing
        if arrayIndex is None:
            return ArrayOfPropertyIdentifier(property_list)

        # asking for the length
        if arrayIndex == 0: