import org.lsst.ccs.description.groovy.CCSBuilder
import org.lsst.ccs.bootstrap.BootstrapResourceUtils
import org.lsst.ccs.subsystem.rafts.RaftsMain
import org.lsst.ccs.subsystem.rafts.REBDevice
import org.lsst.ccs.subsystem.rafts.DacControl
import org.lsst.ccs.subsystem.rafts.AspicControl
import org.lsst.ccs.subsystem.rafts.BiasControl
import org.lsst.ccs.subsystem.rafts.GlobalProc
import org.lsst.ccs.monitor.Channel
import org.lsst.ccs.monitor.Page
import org.lsst.ccs.drivers.reb.SlowAdcs
import org.lsst.ccs.drivers.reb.sim.ClientFactorySimulation
import org.lsst.ccs.monitor.CalcChannel
import org.lsst.ccs.monitor.CalcChannel.Operation

CCSBuilder builder = ["ccs-reb5"]

Properties props = BootstrapResourceUtils.getBootstrapSystemProperties()
def runMode = props.getProperty("org.lsst.ccs.run.mode", "normal")
def rebId = Integer.valueOf(props.getProperty("org.lsst.ccs.reb.id", "88"))
def hdwType = props.getProperty("org.lsst.ccs.reb.hdwtype", "daq")
def ifcName = props.getProperty("org.lsst.ccs.reb.ifcname", null)
def partition = props.getProperty("org.lsst.ccs.reb.partition", "ccs")
def rawAdcs = props.getProperty("org.lsst.ccs.reb.rawadcs", "false").equals("true")

builder.main (RaftsMain) {

    if (runMode.equals("simulation")) {
        clientFactory (ClientFactorySimulation)
    }

    globalProc(GlobalProc, partition: partition, dfltFolder: "base")
    
    def reb = "REB0"

    "$reb" (REBDevice, hdwType: hdwType, id: rebId, ifcName: ifcName) {

        for (int j = 0; j < 6; j++) {
            def apc = "ASPIC$j"
            "${reb}.${apc}" (AspicControl, hwChan: j)
        }

        "${reb}.DAC" (DacControl, raw: rawAdcs)

        for (int j = 0; j < 3; j++) {
            "${reb}.Bias$j" (BiasControl, hwChan: j, raw: rawAdcs)
        }
    }

    "Page0" (Page, id: 0, label: reb)

    String title = "${reb} temperatures\\"
    for (int j = 1; j <= 10; j++) {
        "${reb}.Temp$j" (Channel, description: "${title}Board temperature $j", units: "\u00b0C",
                         devcName: reb, hwChan: j - 1, type: "TEMP", pageId: 0)
        title = ""
    }

    "${reb}.Atemp0U" (Channel, description: "ASPIC 0 upper temp", units: "\u00b0C",
                      devcName: reb, hwChan: 0, type: "ATEMP", pageId: 0)

    "${reb}.Atemp0L" (Channel, description: "ASPIC 0 lower temp", units: "\u00b0C",
                      devcName: reb, hwChan: 1, type: "ATEMP", pageId: 0)

    "${reb}.Atemp1U" (Channel, description: "ASPIC 1 upper temp", units: "\u00b0C",
                      devcName: reb, hwChan: 2, type: "ATEMP", pageId: 0)

    "${reb}.Atemp1L" (Channel, description: "ASPIC 1 lower temp", units: "\u00b0C",
                      devcName: reb, hwChan: 3, type: "ATEMP", pageId: 0)

    "${reb}.Atemp2U" (Channel, description: "ASPIC 2 upper temp", units: "\u00b0C",
                      devcName: reb, hwChan: 4, type: "ATEMP", pageId: 0)

    "${reb}.Atemp2L" (Channel, description: "ASPIC 2 lower temp", units: "\u00b0C",
                      devcName: reb, hwChan: 5, type: "ATEMP", pageId: 0)

    for (int j = 0; j < 3; j++) {
        "${reb}.CCDTemp$j" (Channel, description: "CCD $j temperature", units: "\u00b0C",
                            devcName: reb, hwChan: j, type: "RTD", pageId: 0)
    }

    "${reb}.RTDTemp" (Channel, description: "RTD temperature", units: "\u00b0C",
                      devcName: reb, hwChan: 3, type: "RTD", pageId: 0)

    "${reb}.DigV"    (Channel, description: "${reb} board power\\Digital PS voltage", units: "Volts",
                      devcName: reb, hwChan: 0, type: "POWER", pageId: 0)

    "${reb}.DigI"    (Channel, description: "Digital PS current", format: ".1f", units: "mA",
                      devcName: reb, hwChan: 1, type: "POWER", scale: 1000, pageId: 0)

    "${reb}.DigP"    (CalcChannel, description: "Digital PS power", format: ".2f", units: "Watts",
                      devcName: reb, type:Operation.PROD, channelPaths:["${reb}.DigV","${reb}.DigI"], scale: 0.001, pageId: 0)

    "${reb}.AnaV"    (Channel, description: "Analog PS voltage", units: "Volts",
                      devcName: reb, hwChan: 2, type: "POWER", pageId: 0)

    "${reb}.AnaI"    (Channel, description: "Analog PS current", format: ".1f", units: "mA",
                      devcName: reb, hwChan: 3, type: "POWER", scale: 1000, pageId: 0)

    "${reb}.AnaP"    (CalcChannel, description: "Analog PS power", format: ".2f", units: "Watts",
                      devcName: reb, type:Operation.PROD, channelPaths:["${reb}.AnaV","${reb}.AnaI"], scale: 0.001, pageId: 0)

    "${reb}.ClkHV"   (Channel, description: "Clock High PS voltage", units: "Volts",
                      devcName: reb, hwChan: 4, type: "POWER", pageId: 0)

    "${reb}.ClkHI"   (Channel, description: "Clock High PS current", format: ".1f", units: "mA",
                      devcName: reb, hwChan: 5, type: "POWER", scale: 1000, pageId: 0)

    "${reb}.ClkHP"   (CalcChannel, description: "Clock High PS power", format: ".2f", units: "Watts",
                      devcName: reb, type:Operation.PROD, channelPaths:["${reb}.ClkHV","${reb}.ClkHI"], scale: 0.001, pageId: 0)

    "${reb}.ClkLV"   (Channel, description: "Clock Low PS voltage", units: "Volts",
                      devcName: reb, hwChan: 8, type: "POWER", pageId: 0)

    "${reb}.ClkLI"   (Channel, description: "Clock Low PS current", format: ".1f", units: "mA",
                      devcName: reb, hwChan: 9, type: "POWER", scale: 1000, pageId: 0)

    "${reb}.ClkLP"   (CalcChannel, description: "Clock Low PS power", format: ".2f", units: "Watts",
                      devcName: reb, type:Operation.PROD, channelPaths:["${reb}.ClkLV","${reb}.ClkLI"], scale: 0.001, pageId: 0)

    "${reb}.ODV"     (Channel, description: "OD PS voltage", units: "Volts",
                      devcName: reb, hwChan: 6, type: "POWER", pageId: 0)

    "${reb}.ODI"     (Channel, description: "OD PS current", format: ".1f", units: "mA",
                      devcName: reb, hwChan: 7, type: "POWER", scale: 1000, pageId: 0)

    "${reb}.ODP"     (CalcChannel, description: "OD PS power", format: ".2f", units: "Watts",
                      devcName: reb, type:Operation.PROD, channelPaths:["${reb}.ODV","${reb}.ODI"], scale: 0.001, pageId: 0)

    "${reb}.Power"   (Channel, description: "Total power", format: ".2f", units: "Watts",
                      devcName: reb, hwChan: REBDevice.CHAN_TOTAL_POWER, type: "POWER", pageId: 0)

    "${reb}.PClkU"   (Channel, description: "${reb} clock rails\\Parallel upper", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_CKP_U, type: "BIAS", pageId: 0)

    "${reb}.PClkL"   (Channel, description: "Parallel lower", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_CKP_L, type: "BIAS", pageId: 0)

    "${reb}.SClkU"   (Channel, description: "Serial upper", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_SCK_U, type: "BIAS", pageId: 0)

    "${reb}.SClkL"   (Channel, description: "Serial lower", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_SCK_L, type: "BIAS", pageId: 0)

    "${reb}.RGU"     (Channel, description: "Reset gate upper", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_RG_U, type: "BIAS", pageId: 0)

    "${reb}.RGL"     (Channel, description: "Reset gate lower", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_RG_L, type: "BIAS", pageId: 0)

    "${reb}.RefP12"  (Channel, description: "Positive 12 ref", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VP12, type: "BIAS", pageId: 0)

    "${reb}.RefN12"  (Channel, description: "Negative 12 ref", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VN12, type: "BIAS", pageId: 0)

    "${reb}.OD0V"    (Channel, description: "${reb} bias voltages\\OD 0 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OD_0, type: "BIAS", pageId: 0)

    "${reb}.OG0V"    (Channel, description: "OG 0 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OG_0, type: "BIAS", pageId: 0)

    "${reb}.RD0V"    (Channel, description: "RD 0 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_RD_0, type: "BIAS", pageId: 0)

    "${reb}.GD0V"    (Channel, description: "GD 0 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_GD_0, type: "BIAS", pageId: 0)

    "${reb}.OD1V"    (Channel, description: "OD 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OD_1, type: "BIAS", pageId: 0)

    "${reb}.OG1V"    (Channel, description: "OG 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OG_1, type: "BIAS", pageId: 0)

    "${reb}.RD1V"    (Channel, description: "RD 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_RD_1, type: "BIAS", pageId: 0)

    "${reb}.GD1V"    (Channel, description: "GD 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_GD_1, type: "BIAS", pageId: 0)

    "${reb}.OD2V"    (Channel, description: "OD 2 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OD_2, type: "BIAS", pageId: 0)

    "${reb}.OG2V"    (Channel, description: "OG 2 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_OG_2, type: "BIAS", pageId: 0)

    "${reb}.RD2V"    (Channel, description: "RD 2 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_RD_2, type: "BIAS", pageId: 0)

    "${reb}.GD2V"    (Channel, description: "GD 2 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_GD_2, type: "BIAS", pageId: 0)

    "${reb}.Ref05V"  (Channel, description: "5V ref 0 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VREF5_0, type: "BIAS", pageId: 0)

    "${reb}.Ref15V"  (Channel, description: "5V ref 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VREF5_1, type: "BIAS", pageId: 0)

    "${reb}.Ref25V"  (Channel, description: "5V ref 2 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VREF5_2, type: "BIAS", pageId: 0)

    "${reb}.Ref125V" (Channel, description: "2.5V ref 1 voltage", units: "Volts",
                      devcName: reb, hwChan: SlowAdcs.CHAN_VREF25_1, type: "BIAS", pageId: 0)

    title = "$reb CCD currents\\"
    for (int js = 0; js < 3; js++) {
        for (int jd = 0; jd < 2; jd++) {
            String tb = jd == 0 ? "upper" : "lower"
            int jb = 1 - jd
            for (int jc = 0; jc < 8; jc++) {
                int ch = jc + 8 * jd + 16 * js
                "${reb}.CCDI$js$jb$jc" \
                     (Channel, description: "${title}CCD $js $tb current $jc", format: ".3f", units: "mA",
                      devcName: reb, hwChan: ch, type: "CURR", scale: 1000, pageId: 0)
                title = ""
            }
        }
    }

}
