# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# def get_flags():
#     """
#     Return a list of all flags which are set.
#     """
#     flags = unitdata.kv().getrange('reactive.states.', strip=True) or {}
#     return sorted(flags.keys())
# 
# Path: charms/reactive/flags.py
# def _get_flag_value(flag, default=None):
#     return unitdata.kv().get('reactive.states.%s' % flag, default)
# 
# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# @cmdline.no_output
# def set_flag(flag, value=None):
#     """set_flag(flag)
#     Set the given flag as active.
# 
#     :param str flag: Name of flag to set.
# 
#     .. note:: **Changes to flags are reset when a handler crashes.** Changes to
#        flags happen immediately, but they are only persisted at the end of a
#        complete and successful run of the reactive framework. All unpersisted
#        changes are discarded when a hook crashes.
#     """
#     old_flags = get_flags()
#     unitdata.kv().update({flag: value}, prefix='reactive.states.')
#     if flag not in old_flags:
#         tracer().set_flag(flag)
#         FlagWatch.change(flag)
#         trigger = _get_trigger(flag, None)
#         for flag_name in trigger['set_flag']:
#             set_flag(flag_name)
#         for flag_name in trigger['clear_flag']:
#             clear_flag(flag_name)
#         for callback in trigger['callbacks']:
#             callback()
# 
# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# @cmdline.no_output
# def clear_flag(flag):
#     """
#     Clear / deactivate a flag.
# 
#     :param str flag: Name of flag to set.
# 
#     .. note:: **Changes to flags are reset when a handler crashes.** Changes to
#        flags happen immediately, but they are only persisted at the end of a
#        complete and successful run of the reactive framework. All unpersisted
#        changes are discarded when a hook crashes.
#     """
#     old_flags = get_flags()
#     unitdata.kv().unset('reactive.states.%s' % flag)
#     unitdata.kv().set('reactive.dispatch.removed_state', True)
#     if flag in old_flags:
#         tracer().clear_flag(flag)
#         FlagWatch.change(flag)
#         trigger = _get_trigger(None, flag)
#         for flag_name in trigger['set_flag']:
#             set_flag(flag_name)
#         for flag_name in trigger['clear_flag']:
#             clear_flag(flag_name)
#         for callback in trigger['callbacks']:
#             callback()
# 
# Path: charms/reactive/flags.py
# class StateList(object):
#     """
#     .. deprecated:: 0.5.0
#        use flag instead
# 
#     Base class for a set of states that can be set by a relation or layer.
# 
#     This class should be used so that they can be discovered and introspected,
#     for documentation, composition, or linting.
# 
#     Example usage::
# 
#         class MyRelation(RelationBase):
#             class states(StateList):
#                 connected = State('{relation_name}.connected')
#                 available = State('{relation_name}.available')
#     """
#     pass
# 
# Path: charms/reactive/bus.py
# def _append_path(d):
#     if d not in sys.path:
#         sys.path.append(d)


import os
import sys
import importlib
from inspect import isclass
from charmhelpers.core import hookenv
from charmhelpers.core import unitdata
from charmhelpers.cli import cmdline
from charms.reactive.flags import get_flags
from charms.reactive.flags import _get_flag_value
from charms.reactive.flags import set_flag
from charms.reactive.flags import clear_flag
from charms.reactive.flags import StateList
from charms.reactive.bus import _append_path
    from importlib.metadata import entry_points
    from pkg_resources import iter_entry_points
            'relation': self.relation_name,
            'conversations': [],
        })
        if self.key not in value['conversations']:
            value['conversations'].append(self.key)
        set_flag(state, value)
    set_flag = set_state

    def remove_state(self, state):
        """
        Remove this conversation from the given state, and potentially
        deactivate the state if no more conversations are in it.

        The relation name will be interpolated in the state name, and it is
        recommended that it be included to avoid conflicts with states from
        other relations.  For example::

            conversation.remove_state('{relation_name}.state')

        If called from a converation handling the relation "foo", this will
        remove the conversation from the "foo.state" state, and, if no more
        conversations are in this the state, will deactivate it.
        """
        state = state.format(relation_name=self.relation_name)
        value = _get_flag_value(state)
        if not value:
            return
        if self.key in value['conversations']:
            value['conversations'].remove(self.key)
        if value['conversations']:

# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# def get_flags():
#     """
#     Return a list of all flags which are set.
#     """
#     flags = unitdata.kv().getrange('reactive.states.', strip=True) or {}
#     return sorted(flags.keys())
# 
# Path: charms/reactive/flags.py
# def _get_flag_value(flag, default=None):
#     return unitdata.kv().get('reactive.states.%s' % flag, default)
# 
# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# @cmdline.no_output
# def set_flag(flag, value=None):
#     """set_flag(flag)
#     Set the given flag as active.
# 
#     :param str flag: Name of flag to set.
# 
#     .. note:: **Changes to flags are reset when a handler crashes.** Changes to
#        flags happen immediately, but they are only persisted at the end of a
#        complete and successful run of the reactive framework. All unpersisted
#        changes are discarded when a hook crashes.
#     """
#     old_flags = get_flags()
#     unitdata.kv().update({flag: value}, prefix='reactive.states.')
#     if flag not in old_flags:
#         tracer().set_flag(flag)
#         FlagWatch.change(flag)
#         trigger = _get_trigger(flag, None)
#         for flag_name in trigger['set_flag']:
#             set_flag(flag_name)
#         for flag_name in trigger['clear_flag']:
#             clear_flag(flag_name)
#         for callback in trigger['callbacks']:
#             callback()
# 
# Path: charms/reactive/flags.py
# @cmdline.subcommand()
# @cmdline.no_output
# def clear_flag(flag):
#     """
#     Clear / deactivate a flag.
# 
#     :param str flag: Name of flag to set.
# 
#     .. note:: **Changes to flags are reset when a handler crashes.** Changes to
#        flags happen immediately, but they are only persisted at the end of a
#        complete and successful run of the reactive framework. All unpersisted
#        changes are discarded when a hook crashes.
#     """
#     old_flags = get_flags()
#     unitdata.kv().unset('reactive.states.%s' % flag)
#     unitdata.kv().set('reactive.dispatch.removed_state', True)
#     if flag in old_flags:
#         tracer().clear_flag(flag)
#         FlagWatch.change(flag)
#         trigger = _get_trigger(None, flag)
#         for flag_name in trigger['set_flag']:
#             set_flag(flag_name)
#         for flag_name in trigger['clear_flag']:
#             clear_flag(flag_name)
#         for callback in trigger['callbacks']:
#             callback()
# 
# Path: charms/reactive/flags.py
# class StateList(object):
#     """
#     .. deprecated:: 0.5.0
#        use flag instead
# 
#     Base class for a set of states that can be set by a relation or layer.
# 
#     This class should be used so that they can be discovered and introspected,
#     for documentation, composition, or linting.
# 
#     Example usage::
# 
#         class MyRelation(RelationBase):
#             class states(StateList):
#                 connected = State('{relation_name}.connected')
#                 available = State('{relation_name}.available')
#     """
#     pass
# 
# Path: charms/reactive/bus.py
# def _append_path(d):
#     if d not in sys.path:
#         sys.path.append(d)


# Path: charms/reactive/relations.py
import os
import sys
import importlib
from inspect import isclass
from charmhelpers.core import hookenv
from charmhelpers.core import unitdata
from charmhelpers.cli import cmdline
from charms.reactive.flags import get_flags
from charms.reactive.flags import _get_flag_value
from charms.reactive.flags import set_flag
from charms.reactive.flags import clear_flag
from charms.reactive.flags import StateList
from charms.reactive.bus import _append_path
    from importlib.metadata import entry_points
    from pkg_resources import iter_entry_points

            'relation': self.relation_name,
            'conversations': [],
        })
        if self.key not in value['conversations']:
            value['conversations'].append(self.key)
        set_flag(state, value)
    set_flag = set_state

    def remove_state(self, state):
        """
        Remove this conversation from the given state, and potentially
        deactivate the state if no more conversations are in it.

        The relation name will be interpolated in the state name, and it is
        recommended that it be included to avoid conflicts with states from
        other relations.  For example::

            conversation.remove_state('{relation_name}.state')

        If called from a converation handling the relation "foo", this will
        remove the conversation from the "foo.state" state, and, if no more
        conversations are in this the state, will deactivate it.
        """
        state = state.format(relation_name=self.relation_name)
        value = _get_flag_value(state)
        if not value:
            return
        if self.key in value['conversations']:
            value['conversations'].remove(self.key)
        if value['conversations']:

            set_flag(state, value)