# Import all of the H1 states.py and then add on the extra BRS things
from guardian import GuardState, GuardStateDecorator
from guardian.manager import Node
from cdsutils import getdata
import re
from states import *

# If we dont manage the BRS_STAT node, then we dont need to redefine a state
# This will be better for now, but we may wnat to rethink later.


# Determine which node to use, but dont manage
BRS_node_dict = {'ETMX':'BRSX_STAT',
                 'ETMY':'BRSY_STAT'}

try:
    bsc_re = re.compile('(?<=(ITM|ETM)([X,Y]))|_(BS)_')
    grp = bsc_re.search(_SYSTEM_).groups()
except AttributeError:
    raise '_SYSTEM_ name does not match re for BRS_STAT nodes'

if grp[0]:
    BRS_STAT = BRS_node_dict[''.join([grp[0],grp[1]])]
elif not grp[0]:
    BRS_STAT = BRS_node_dict[grp[2]]
    
BRS_STAT_man = Node(BRS_STAT)



#############################################
# New states and decorators


class BRS_FAULT_SC_OFF(GuardState):
    """
    Jump here is there is a fault in the brs stat node.
    If it is damping, wait for it to stop before moving on.
    If it is in fault or the velocity is huge, stop here and notify.
    Make it a protected state so it wont jump away.
    Anything else???
    """
    request = False
    redirect = False
    def main(self):
        self.max_v = 10000
        # FIXME: For now we are just going to turn off all of the SC.
        # We cannot be general here unfortunately, we will have to know
        # which dofs we can turn off (X & Y in this case).
        self.banks = {}
        for dof, fm in {'X': 0, 'Y': 0}.items():
            log('{}, {}'.format(dof, fm))
            bank = 'SENSCOR_{}'.format(dof)
            self.banks[dof] = Fader(bank)
            self.banks[dof].start_fade(fm)
        
    def run(self):
        for dof, fader in self.banks.items():
            if fader.is_fading:
                notify('Turning OFF SC')
                return False
        # Double check that it actually faded, sometimes it wont even with the retries
        for dof, fader in self.banks.items():
            if fader.get_cur_filter()[0] != 0:
                # I guess try again if it didnt fade after 2 tries
                return 'BRS_FAULT_SC_OFF'
        # After it has turned off the SC, we can check if the BRS has
        # returned to a usable state.
        brs_state = BRS_STAT_man.STATE
        if brs_state == 'FAULT':
            notify('BRS is in FAULT, staying here')
            return False
        # If the damper is on check that the velocity is not too high
        elif brs_state == 'DAMPER_ON_HIGH_VEL':
            notify('BRS velocity is too high, waiting here')
            return False
        else:
            return True


class check_brs(GuardStateDecorator):
    """
    Used as a decorator to see if the BRS has drifted or if there
    is other issues. Jump to no SC if there is an issue (I guess?).
    """
    def pre_exec(self):
        if BRS_STAT_man.STATE == 'FAULT' or BRS_STAT_man.STATE == 'DAMPER_ON_HIGH_VEL':
            return 'BRS_FAULT_SC_OFF'



# In order to add a decorator to an existing state method,
# we need to wrap the method from the class's dictionary.
# See https://stackoverflow.com/a/33868946
CONFIG_WINDY.run = check_brs(CONFIG_WINDY.__dict__['run'])
CONFIG_USEISM.run = check_brs(CONFIG_USEISM.__dict__['run'])
CONFIG_EQ.run = check_brs(CONFIG_EQ.__dict__['run'])
