# Path: avatar2/watchmen.py
# AFTER = 'after'
# 
# BEFORE = 'before'
# 
# def watch(watched_type):
#     """
#     Decorator for the watchmen system
#     """
# 
#     def decorator(func):
#         @wraps(func)
#         def watchtrigger(self, *args, **kwargs):
#             # To avoid circular dependencies, we import here ...
#             from .avatar2 import Avatar
#             from .targets.target import Target
# 
#             cb_kwargs = dict(kwargs)
#             if isinstance(self, Avatar):
#                 avatar = self
#             elif isinstance(self, Target):
#                 avatar = self.avatar
#                 cb_kwargs['watched_target'] = self
# 
#             avatar.watchmen.t(watched_type, BEFORE, *args, **cb_kwargs)
#             ret = func(self, *args, **kwargs)
#             cb_kwargs.update({'watched_return': ret})
#             cb_ret = avatar.watchmen.t(watched_type, AFTER, *args, **cb_kwargs)
# 
#             return ret if cb_ret is None else cb_ret
# 
#         return watchtrigger
# 
#     return decorator
# 
# Path: avatar2/targets/target.py
# class TargetStates(IntEnum):
#     """
#     A simple Enum for the different states a target can be in.
#     """
#     CREATED = 0x1
#     INITIALIZED = 0x2
#     STOPPED = 0x4
#     RUNNING = 0x8
#     SYNCING = 0x10
#     EXITED = 0x20
#     NOT_RUNNING = INITIALIZED | STOPPED
#     BREAKPOINT = SYNCING | STOPPED


from types import MethodType
from threading import Event
from enum import Enum
from avatar2.watchmen import AFTER, BEFORE, watch
from avatar2 import TargetStates

@watch('OrchestrationResumed')
def resume_orchestration(self, blocking=True):
    if self.last_target == None:
        raise Exception("No Orchestration was running before!")
    self._orchestrate(self.last_target, blocking)


@watch('OrchestrationStop')
def stop_orchestration(self, reason=OrchestrationStopReason.USER_REQUESTED):
    for t in self.targets.values():
        if t.state == TargetStates.RUNNING:
            t.stop()
    self.disable_transitions()
    self.orchestration_stopped.set()
    self.orchestration_stopped_reason = reason


def load_plugin(avatar):
    avatar.transitions = {}
    avatar.orchestration_stopped = Event()
    avatar.orchestration_stopped.set()
    avatar.orchestration_stopped_reason = None

    avatar.start_target = None
    avatar.last_target = None

    avatar.watchmen.add_watch_types(watched_events)
    avatar.watchmen.add_watchman('BreakpointHit', when=AFTER,
                                 callback=transition_callback)

# Path: avatar2/watchmen.py
# AFTER = 'after'
# 
# BEFORE = 'before'
# 
# def watch(watched_type):
#     """
#     Decorator for the watchmen system
#     """
# 
#     def decorator(func):
#         @wraps(func)
#         def watchtrigger(self, *args, **kwargs):
#             # To avoid circular dependencies, we import here ...
#             from .avatar2 import Avatar
#             from .targets.target import Target
# 
#             cb_kwargs = dict(kwargs)
#             if isinstance(self, Avatar):
#                 avatar = self
#             elif isinstance(self, Target):
#                 avatar = self.avatar
#                 cb_kwargs['watched_target'] = self
# 
#             avatar.watchmen.t(watched_type, BEFORE, *args, **cb_kwargs)
#             ret = func(self, *args, **kwargs)
#             cb_kwargs.update({'watched_return': ret})
#             cb_ret = avatar.watchmen.t(watched_type, AFTER, *args, **cb_kwargs)
# 
#             return ret if cb_ret is None else cb_ret
# 
#         return watchtrigger
# 
#     return decorator
# 
# Path: avatar2/targets/target.py
# class TargetStates(IntEnum):
#     """
#     A simple Enum for the different states a target can be in.
#     """
#     CREATED = 0x1
#     INITIALIZED = 0x2
#     STOPPED = 0x4
#     RUNNING = 0x8
#     SYNCING = 0x10
#     EXITED = 0x20
#     NOT_RUNNING = INITIALIZED | STOPPED
#     BREAKPOINT = SYNCING | STOPPED


# Path: avatar2/plugins/orchestrator.py
from types import MethodType
from threading import Event
from enum import Enum
from avatar2.watchmen import AFTER, BEFORE, watch
from avatar2 import TargetStates


@watch('OrchestrationResumed')
def resume_orchestration(self, blocking=True):
    if self.last_target == None:
        raise Exception("No Orchestration was running before!")
    self._orchestrate(self.last_target, blocking)


@watch('OrchestrationStop')
def stop_orchestration(self, reason=OrchestrationStopReason.USER_REQUESTED):
    for t in self.targets.values():
        if t.state == TargetStates.RUNNING:
            t.stop()
    self.disable_transitions()
    self.orchestration_stopped.set()
    self.orchestration_stopped_reason = reason


def load_plugin(avatar):
    avatar.transitions = {}
    avatar.orchestration_stopped = Event()
    avatar.orchestration_stopped.set()
    avatar.orchestration_stopped_reason = None

    avatar.start_target = None
    avatar.last_target = None

    avatar.watchmen.add_watch_types(watched_events)
    avatar.watchmen.add_watchman('BreakpointHit', when=AFTER,
                                 callback=transition_callback)

    avatar.watchmen.add_watchman('UpdateState', when=AFTER,