import org.lsst.ccs.description.groovy.CCSBuilder
import org.lsst.ccs.bootstrap.BootstrapResourceUtils
import org.lsst.ccs.subsystem.power.PowerControl
import org.lsst.ccs.subsystem.power.BK1696Device
import org.lsst.ccs.subsystem.power.CpfeDevice
import org.lsst.ccs.subsystem.power.RebPower
import org.lsst.ccs.subsystem.power.SimPowerDevice
import org.lsst.ccs.subsystem.power.RebPsDeviceOld
import org.lsst.ccs.monitor.Channel
import org.lsst.ccs.monitor.Page
import org.lsst.ccs.monitor.CalcChannel
import org.lsst.ccs.monitor.CalcChannel.Operation

Properties props = BootstrapResourceUtils.getBootstrapSystemProperties()
def runMode = props.getProperty("org.lsst.ccs.run.mode", "normal")
if (runMode.equals("simulation")) {
    mainPsType = "sim"
    mainPsAttributes = [loads:[50] as double[]]
    isProto = true
} else {
    mainPsType = props.getProperty("org.lsst.ccs.main.ps.type", "bk1696")
    mainPsAttributes = ""
    isProto = props.getProperty("org.lsst.ccs.ps.version", "prod").equals("proto")
}    
int nReb = isProto ? 3 : 6
int nTemp = isProto ? 1 : 7
def mainDevice = mainPsType.equals("bk1696") ? BK1696Device : mainPsType.equals("cpfe") ? CpfeDevice :
                 mainPsType.equals("sim") ? SimPowerDevice : null
boolean haveMainPs = mainDevice != null
boolean haveMainPsTemp = mainDevice == CpfeDevice

def ps0 = "PS0"

CCSBuilder builder = ["rebps-cr"]

builder.main (RebPower) {

    "$ps0" (RebPsDeviceOld)

    if (haveMainPs) {

        MainPS (mainDevice) {

            MainCtrl (PowerControl, description: "Main PS control", hwChan: 0)
        }

        "Common/MainVoltage" (Channel, description: "Main PS voltage", units: "Volts",
                              devcName: "MainPS", hwChan: 0, type: "VOLTAGE")

        "Common/MainCurrent" (Channel, description: "Main PS current", format: ".1f", units: "mA",
                              devcName: "MainPS", hwChan: 0, type: "CURRENT", scale: 1000)

        "Common/MainPower"   (CalcChannel, description: "Main PS Power", format: ".2f", units: "Watts",
                              devcName: "MainPS", hwChan: 0, type:Operation.PROD, channelPaths:["Common/MainVoltage","Common/MainCurrent"], scale: 0.001)

        if (haveMainPsTemp) {
            "Common/MainTemp" (Channel, description: "Main PS Temperature", units: "\u00b0C",
                               devcName: "MainPS", hwChan: 0, type: "TEMP")
        }
    }

    for (int i = 0; i < nTemp; i++) {
        "Common/BoardTemp$i" (Channel, description: "Board temperature $i", units: "\u00b0C",
                              devcName: "$ps0", hwChan: i, type: "TEMP")
    }

    for (int i = 0; i < nReb; i++) {
        ix = i % 3
        if (ix == 2) continue

        reb = "REB$i"

        psn = "Digital"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        psn = "Analog"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        psn = "OD"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/VaftLDO2" (Channel, description: "$psn voltage after LDO2", units: "Volts",
                                  devcName: "$ps0", hwChan: 5, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        psn = "Clockhi"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        psn = "Clocklo"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/VaftLDO2" (Channel, description: "$psn voltage after LDO2", units: "Volts",
                                  devcName: "$ps0", hwChan: 5, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        psn = "Dphi"

        "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                 devcName: "$ps0", hwChan: 2, type: "$i:$psn")

        "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                 devcName: "$ps0", hwChan: 3, type: "$i:$psn", scale: 1000)

        "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 4, type: "$i:$psn")

        if (ix == 0) {
            psn = "Heater"
            apsn = "Digital"
            ai = i + 2

            "${reb}/${psn}/VbefLDO" (Channel, description: "$psn voltage before LDO", units: "Volts",
                                     devcName: "$ps0", hwChan: 0, type: "$ai:$apsn")

            "${reb}/${psn}/IbefLDO" (Channel, description: "$psn current before LDO", format: ".1f", units: "mA",
                                     devcName: "$ps0", hwChan: 1, type: "$ai:$apsn", scale: 1000)

            "${reb}/${psn}/VaftLDO" (Channel, description: "$psn voltage after LDO", units: "Volts",
                                     devcName: "$ps0", hwChan: 2, type: "$ai:$apsn")

            "${reb}/${psn}/IaftLDO" (Channel, description: "$psn current after LDO", format: ".1f", units: "mA",
                                     devcName: "$ps0", hwChan: 3, type: "$ai:$apsn", scale: 1000)

            "${reb}/${psn}/VaftSwch" (Channel, description: "$psn voltage after switch", units: "Volts",
                                      devcName: "$ps0", hwChan: 4, type: "$ai:$apsn")
        }

        psn = "Hvbias"

        "${reb}/${psn}/VbefSwch" (Channel, description: "$psn voltage before switch", units: "Volts",
                                  devcName: "$ps0", hwChan: 0, type: "$i:$psn")

        "${reb}/${psn}/IbefSwch" (Channel, description: "$psn current before switch", format: ".3f", units: "mA",
                                  devcName: "$ps0", hwChan: 1, type: "$i:$psn", scale: 1000)

        "${reb}/Power"           (Channel, description: "$reb all PSs\\Total power", units: "Watts",
                                  devcName: "$ps0", hwChan: 0, type: "$i:POWER")

    }

}
