import org.lsst.ccs.description.groovy.CCSBuilder;
import org.lsst.ccs.subsystem.mcm.MCM_IR2;
import org.lsst.ccs.subsystem.mcm.MinionIR2;
import org.lsst.ccs.subsystem.mcm.MinionIR2Group;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher.AlertHandler;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher.AlertAction;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher.EmailAlertAction;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher.EmailAlertActionFromFile;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher.CommandAlertAction;
import org.lsst.ccs.subsystem.mcm.AlertDispatcher;
import org.lsst.ccs.subsystem.mcm.AlertNotification;
import org.lsst.ccs.subsystem.rafts.alerts.RaftAlert;
import org.lsst.ccs.bus.states.AlertState;
import java.util.function.Predicate;
import org.lsst.ccs.subsystem.mcm.ir2.actions.RebTemperatureTooHighAction
import org.lsst.ccs.bootstrap.BootstrapResourceUtils;

CCSBuilder builder = ["mcm-ir2"]

Properties props = BootstrapResourceUtils.getBootstrapSystemProperties()
def isSimulated = props.getProperty("org.lsst.ccs.run.mode", "normal").equals("simulation")


def fromEmail = isSimulated ? "SIMULATED-ccs-alarm@lsst-mcm.slac.stanford.edu" : "ccs-alarm@lsst-mcm.slac.stanford.edu"
def replyToEmail = isSimulated ? "SIMULATED-lsstcam-opsprob@slac.stanford.edu" : "lsstcam-opsprob@slac.stanford.edu";

def infrastructureList = ["turri@slac.stanford.edu"];


def environmentList = isSimulated ? infrastructureList : ["jtice@SLAC.Stanford.EDU","tether@slac.stanford.edu","marshall@slac.stanford.edu"];
def ts7List = isSimulated ? infrastructureList : ["turri@slac.stanford.edu","tonyj@slac.stanford.edu","marshall@slac.stanford.edu"];
//Global selectors
def alarmSelector = {notification -> return notification.getSeverity() == AlertState.ALARM } as Predicate<AlertNotification>
def warningSelector = {notification -> return notification.getSeverity() == AlertState.WARNING } as Predicate<AlertNotification>



//Raft selectors
def raftOriginSelector = { n -> return n.getSubsystemType().equals(MinionIR2.RAFT) } as Predicate<AlertNotification>
def rebConnectionAlertSelector = { n -> return n.getAlert().getAlertId() ==  RaftAlert.REB_NOT_CONNECTED.getAlertId() } as Predicate<AlertNotification>
def rebConnectionActionSelector = raftOriginSelector.and(rebConnectionAlertSelector);


//Dummy AlertAction to print something
class PrintWhatToDo extends AlertAction {
    def msg;
    PrintWhatToDo(String msg) {
        this.msg = msg;
    }
        
    def void accept(AlertNotification notif) {
        System.out.println(notif.getSeverity().toString()+" "+msg);
    }        

    def String getDescription() {
        return "Prints to standard output: "+msg;
    }        
}


builder.
    main(MCM_IR2, 
        minions:[(MinionIR2Group.INFRASTRUCTURE):["jython-server":MinionIR2.JYTHONCONSOLE, "localdb":MinionIR2.LOCALBD, "rest-server":MinionIR2.REST_SERVER, "mcm-ir2":MinionIR2.MCM, "clusterMonitor":MinionIR2.CLUSTER_MONITOR],
                 (MinionIR2Group.IR2_ENVIRONMENT) :["ir2-airwatch":MinionIR2.AIRWATCH,"ccs-doorman":MinionIR2.DOORMAN],
                 (MinionIR2Group.ALIVENESS_TEST) :["aliveness-rebps":MinionIR2.POWER, "aliveness-raft":MinionIR2.RAFT],
                 (MinionIR2Group.TS71G) :["ts7-1":MinionIR2.TS7, "ts7-rebps":MinionIR2.POWER, "ts8-raft":MinionIR2.RAFT],
                 (MinionIR2Group.TEST_STAND_8) :["ts8-bench":MinionIR2.TS8_BENCH],
                 (MinionIR2Group.METROLOGY) :["metrology":MinionIR2.METROLOGY, "ts7-2":MinionIR2.TS7]] ) {

    infrastructure (AlertDispatcher, group: MinionIR2Group.INFRASTRUCTURE) {
        infrastructureEmailNotification (AlertHandler, handlerName: "infrastructureEmailNotification") {
            infrastructurePublicMailAction (EmailAlertAction, email: infrastructureList, fromEmail:"$fromEmail", replyToEmail:"$replyToEmail")
        }        
    }
    
    environment (AlertDispatcher, group: MinionIR2Group.IR2_ENVIRONMENT) {
        environmentEmailNotification (AlertHandler, handlerName: "environmentEmailNotification") {
             environmentPublicMailAction (EmailAlertAction, email: environmentList, fromEmail:"$fromEmail", replyToEmail:"$replyToEmail")
        }        
    }

    ts71gTest (AlertDispatcher, group: MinionIR2Group.TS71G) {
        ts71gEmailNotification (AlertHandler, handlerName: "ts71gEmailNotification") {
            publicMailAction (EmailAlertAction, email: ts7List, fromEmail:"$fromEmail", replyToEmail:"$replyToEmail")
            privateMailAction (EmailAlertActionFromFile, filePath:"/etc/ccs/emails.list", fromEmail:"$fromEmail", replyToEmail:"$replyToEmail")
        }
        rebTemperatureTooHighHandler (AlertHandler, handlerName: "rebTemperatureTooHighHandler") {
            rebTemperatureTooHighAction (RebTemperatureTooHighAction)
        }        
        rebConnectionActions (AlertHandler, handlerName: "rebConnectionActions", selector: rebConnectionActionSelector ) {
            printWhatToDo2 (PrintWhatToDo, msg: "REB CONNECTION: Something needs to be done")
        }
    }
    
}
