<commit_before>"""
The DUL's finite state machine representation.
"""
import logging
import socket

from pynetdicom3.pdu import (A_ASSOCIATE_RQ, A_ASSOCIATE_RJ, A_ASSOCIATE_AC,
                             P_DATA_TF, A_RELEASE_RQ, A_RELEASE_RP, A_ABORT_RQ)
from pynetdicom3.pdu_primitives import A_ABORT

LOGGER = logging.getLogger('pynetdicom3.sm')

# pylint: disable=invalid-name


class StateMachine(object):
    """Implementation of the DICOM Upper Layer State Machine.

    Seer PS3.8 Section 9.2.

    Attributes
    ----------
    current_state : str
        The current state of the state machine, 'Sta1' to 'Sta13'.
    dul : pynetdicom3.dul.DULServiceProvider
        The DICOM Upper Layer service instance for the local AE
    """
    def __init__(self, dul):
        """Create a new StateMachine.

        Parameters
        ---------
        dul : pynetdicom3.dul.DULServiceProvider
            The DICOM Upper Layer Service instance for the local AE.
        """
        self.current_state = 'Sta1'
        self.dul = dul

    def do_action(self, event):
        """Execute the action triggered by `event`.

        Parameters
        ----------
        event : str
            The event to be processed, 'Evt1' to 'Evt19'
        """
        # Check (event + state) is valid
        if (event, self.current_state) not in TRANSITION_TABLE:
            LOGGER.error("DUL State Machine received an invalid event '%s' "
                         "for the current state '%s'",
                         event, self.current_state)
            raise KeyError("DUL State Machine received an invalid event "
                           "'{}' for the current state '{}'"
                           .format(event, self.current_state))

        action_name = TRANSITION_TABLE[(event, self.current_state)]

        # action is the (description, function, state) tuple
        #   associated with the action_name
        action = ACTIONS[action_name]

        # Attempt to execute the action and move the state machine to its
        #   next state
        try:
            # Execute the required action
            next_state = action[1](self.dul)

            #print(action_name, self.current_state, event, next_state)

            # Move the state machine to the next state
            self.transition(next_state)

        except Exception as ex:
            LOGGER.error("DUL State Machine received an exception attempting "
                         "to perform the action '%s' while in state '%s'",
                         action_name, self.current_state)
            self.dul.kill_dul()
            raise ex

    def transition(self, state):
        """Transition the state machine to the next state.

        Parameters
        ----------
        state : str
            The state to transition to, 'Sta1' to 'Sta13'.

        Raises
        ------
        ValueError
            If `state` is not a valid state.
        """
        # Validate that state is acceptable
        if state in STATES.keys():
            self.current_state = state
        else:
            LOGGER.error('Invalid state "%s" for State Machine', state)
            raise ValueError('Invalid state "%s" for State Machine', state)


def AE_1(dul):
    """Association establishment action AE-1.

    From Idle state, local AE issues a connection request to a remote. This<commit_msg>Changed reraise in fsm.do_action to keep stack trace. (#115)<commit_after>"""
The DUL's finite state machine representation.
"""
import logging
import socket

from pynetdicom3.pdu import (A_ASSOCIATE_RQ, A_ASSOCIATE_RJ, A_ASSOCIATE_AC,
                             P_DATA_TF, A_RELEASE_RQ, A_RELEASE_RP, A_ABORT_RQ)
from pynetdicom3.pdu_primitives import A_ABORT

LOGGER = logging.getLogger('pynetdicom3.sm')

# pylint: disable=invalid-name


class StateMachine(object):
    """Implementation of the DICOM Upper Layer State Machine.

    Seer PS3.8 Section 9.2.

    Attributes
    ----------
    current_state : str
        The current state of the state machine, 'Sta1' to 'Sta13'.
    dul : pynetdicom3.dul.DULServiceProvider
        The DICOM Upper Layer service instance for the local AE
    """
    def __init__(self, dul):
        """Create a new StateMachine.

        Parameters
        ---------
        dul : pynetdicom3.dul.DULServiceProvider
            The DICOM Upper Layer Service instance for the local AE.
        """
        self.current_state = 'Sta1'
        self.dul = dul

    def do_action(self, event):
        """Execute the action triggered by `event`.

        Parameters
        ----------
        event : str
            The event to be processed, 'Evt1' to 'Evt19'
        """
        # Check (event + state) is valid
        if (event, self.current_state) not in TRANSITION_TABLE:
            LOGGER.error("DUL State Machine received an invalid event '%s' "
                         "for the current state '%s'",
                         event, self.current_state)
            raise KeyError("DUL State Machine received an invalid event "
                           "'{}' for the current state '{}'"
                           .format(event, self.current_state))

        action_name = TRANSITION_TABLE[(event, self.current_state)]

        # action is the (description, function, state) tuple
        #   associated with the action_name
        action = ACTIONS[action_name]

        # Attempt to execute the action and move the state machine to its
        #   next state
        try:
            # Execute the required action
            next_state = action[1](self.dul)

            #print(action_name, self.current_state, event, next_state)

            # Move the state machine to the next state
            self.transition(next_state)

        except Exception as ex:
            LOGGER.error("DUL State Machine received an exception attempting "
                         "to perform the action '%s' while in state '%s'",
                         action_name, self.current_state)
            self.dul.kill_dul()
            raise

    def transition(self, state):
        """Transition the state machine to the next state.

        Parameters
        ----------
        state : str
            The state to transition to, 'Sta1' to 'Sta13'.

        Raises
        ------
        ValueError
            If `state` is not a valid state.
        """
        # Validate that state is acceptable
        if state in STATES.keys():
            self.current_state = state
        else:
            LOGGER.error('Invalid state "%s" for State Machine', state)
            raise ValueError('Invalid state "%s" for State Machine', state)


def AE_1(dul):
    """Association establishment action AE-1.

    From Idle state, local AE issues a connection request to a remote. This
{'fraction_non_alphanumeric': 0.08880023640661938, 'fraction_numerical': 0.006944444444444444, 'mean_word_length': 1.8853367433930093, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7347231', 'n_tokens_mistral': 1913, 'n_tokens_neox': 1821, 'n_words': 614}