#!/usr/bin/env python3
from caproto.server import (
    pvproperty,
    PVGroup,
    ioc_arg_parser,
    run,
    SubGroup,
    get_pv_pair_wrapper,
)

pvproperty_with_rbv = get_pv_pair_wrapper(setpoint_suffix="", readback_suffix="_RBV")
unknown = int


class MCAROIGroup(PVGroup):
    label = pvproperty(value="label", name="NM")
    count = pvproperty(value=1, name="", read_only=True)
    net_count = pvproperty(name="N", dtype=unknown, read_only=True)
    preset_count = pvproperty(name="P", dtype=unknown)
    is_preset = pvproperty(name="IP", dtype=unknown)
    bkgnd_chans = pvproperty(name="BG", dtype=unknown)
    hi_chan = pvproperty(name="HI", dtype=unknown)
    lo_chan = pvproperty(name="LO", dtype=unknown)


class EpicsMCAGroup(PVGroup):
    stop_signal = pvproperty(name="Stop", dtype=unknown)
    preset_real_time = pvproperty(name=".PRTM", dtype=unknown)
    preset_live_time = pvproperty(name=".PLTM", dtype=unknown)
    elapsed_real_time = pvproperty(name=".ERTM", dtype=unknown, read_only=True)
    elapsed_live_time = pvproperty(name=".ELTM", dtype=unknown, read_only=True)
    spectrum = pvproperty(name="", dtype=float, read_only=True)
    background = pvproperty(name=".BG", dtype=unknown, read_only=True)
    mode = pvproperty(value="List", name=".MODE", dtype=str)

    class RoisGroup(PVGroup):
        roi0 = SubGroup(MCAROIGroup, prefix=".R0")
        roi1 = SubGroup(MCAROIGroup, prefix=".R1")
        roi2 = SubGroup(MCAROIGroup, prefix=".R2")
        roi3 = SubGroup(MCAROIGroup, prefix=".R3")
        roi4 = SubGroup(MCAROIGroup, prefix=".R4")
        roi5 = SubGroup(MCAROIGroup, prefix=".R5")
        roi6 = SubGroup(MCAROIGroup, prefix=".R6")
        roi7 = SubGroup(MCAROIGroup, prefix=".R7")
        roi8 = SubGroup(MCAROIGroup, prefix=".R8")
        roi9 = SubGroup(MCAROIGroup, prefix=".R9")
        roi10 = SubGroup(MCAROIGroup, prefix=".R10")
        roi11 = SubGroup(MCAROIGroup, prefix=".R11")
        roi12 = SubGroup(MCAROIGroup, prefix=".R12")
        roi13 = SubGroup(MCAROIGroup, prefix=".R13")
        roi14 = SubGroup(MCAROIGroup, prefix=".R14")
        roi15 = SubGroup(MCAROIGroup, prefix=".R15")
        roi16 = SubGroup(MCAROIGroup, prefix=".R16")
        roi17 = SubGroup(MCAROIGroup, prefix=".R17")
        roi18 = SubGroup(MCAROIGroup, prefix=".R18")
        roi19 = SubGroup(MCAROIGroup, prefix=".R19")
        roi20 = SubGroup(MCAROIGroup, prefix=".R20")
        roi21 = SubGroup(MCAROIGroup, prefix=".R21")
        roi22 = SubGroup(MCAROIGroup, prefix=".R22")
        roi23 = SubGroup(MCAROIGroup, prefix=".R23")
        roi24 = SubGroup(MCAROIGroup, prefix=".R24")
        roi25 = SubGroup(MCAROIGroup, prefix=".R25")
        roi26 = SubGroup(MCAROIGroup, prefix=".R26")
        roi27 = SubGroup(MCAROIGroup, prefix=".R27")
        roi28 = SubGroup(MCAROIGroup, prefix=".R28")
        roi29 = SubGroup(MCAROIGroup, prefix=".R29")
        roi30 = SubGroup(MCAROIGroup, prefix=".R30")
        roi31 = SubGroup(MCAROIGroup, prefix=".R31")

    rois = SubGroup(RoisGroup, prefix="")

    start = pvproperty(name="Start", dtype=unknown)
    erase = pvproperty(name="Erase", dtype=unknown)
    erase_start = pvproperty(name="EraseStart", dtype=unknown)
    check_acquiring = pvproperty(name="CheckACQG", dtype=unknown)
    client_wait = pvproperty(name="ClientWait", dtype=unknown)
    enable_wait = pvproperty(name="EnableWait", dtype=unknown)
    force_read = pvproperty(name="Read", dtype=unknown)
    set_client_wait = pvproperty(name="SetClientWait", dtype=unknown)
    status = pvproperty(name="Status", dtype=unknown)
    when_acq_stops = pvproperty(name="WhenAcqStops", dtype=unknown)
    why1 = pvproperty(name="Why1", dtype=unknown)
    why2 = pvproperty(name="Why2", dtype=unknown)
    why3 = pvproperty(name="Why3", dtype=unknown)
    why4 = pvproperty(name="Why4", dtype=unknown)


class EpicsDXPGroup(PVGroup):
    preset_mode = pvproperty_with_rbv(value="Live time", name="PresetMode", dtype=str)
    live_time_output = pvproperty_with_rbv(
        value="livetimeoutput", name="LiveTimeOutput", dtype=str
    )
    elapsed_live_time = pvproperty(name="ElapsedLiveTime", dtype=unknown)
    elapsed_real_time = pvproperty(name="ElapsedRealTime", dtype=unknown)
    elapsed_trigger_live_time = pvproperty(name="ElapsedTriggerLiveTime", dtype=unknown)
    trigger_peaking_time = pvproperty_with_rbv(name="TriggerPeakingTime", dtype=unknown)
    trigger_threshold = pvproperty_with_rbv(name="TriggerThreshold", dtype=unknown)
    trigger_gap_time = pvproperty_with_rbv(name="TriggerGapTime", dtype=unknown)
    trigger_output = pvproperty_with_rbv(
        value="trigger_output", name="TriggerOutput", dtype=str
    )
    max_width = pvproperty_with_rbv(name="MaxWidth", dtype=unknown)
    peaking_time = pvproperty_with_rbv(name="PeakingTime", dtype=unknown)
    energy_threshold = pvproperty_with_rbv(name="EnergyThreshold", dtype=unknown)
    gap_time = pvproperty_with_rbv(name="GapTime", dtype=unknown)
    baseline_cut_percent = pvproperty_with_rbv(name="BaselineCutPercent", dtype=unknown)
    baseline_cut_enable = pvproperty_with_rbv(name="BaselineCutEnable", dtype=unknown)
    baseline_filter_length = pvproperty_with_rbv(
        name="BaselineFilterLength", dtype=unknown
    )
    baseline_threshold = pvproperty_with_rbv(name="BaselineThreshold", dtype=unknown)
    baseline_energy_array = pvproperty(name="BaselineEnergyArray", dtype=unknown)
    baseline_histogram = pvproperty(name="BaselineHistogram", dtype=unknown)
    preamp_gain = pvproperty_with_rbv(name="PreampGain", dtype=unknown)
    detector_polarity = pvproperty_with_rbv(name="DetectorPolarity", dtype=unknown)
    reset_delay = pvproperty_with_rbv(name="ResetDelay", dtype=unknown)
    decay_time = pvproperty_with_rbv(name="DecayTime", dtype=unknown)
    max_energy = pvproperty_with_rbv(name="MaxEnergy", dtype=unknown)
    adc_percent_rule = pvproperty_with_rbv(name="ADCPercentRule", dtype=unknown)
    triggers = pvproperty(name="Triggers", dtype=unknown, read_only=True)
    events = pvproperty(name="Events", dtype=unknown, read_only=True)
    overflows = pvproperty(name="Overflows", dtype=unknown, read_only=True)
    underflows = pvproperty(name="Underflows", dtype=unknown, read_only=True)
    input_count_rate = pvproperty(name="InputCountRate", dtype=unknown, read_only=True)
    output_count_rate = pvproperty(
        name="OutputCountRate", dtype=unknown, read_only=True
    )
    mca_bin_width = pvproperty(name="MCABinWidth_RBV", dtype=unknown, read_only=True)
    calibration_energy = pvproperty(
        name="CalibrationEnergy_RBV", dtype=unknown, read_only=True
    )
    current_pixel = pvproperty(name="CurrentPixel", dtype=unknown)
    dynamic_range = pvproperty(name="DynamicRange_RBV", dtype=unknown, read_only=True)
    preset_events = pvproperty_with_rbv(name="PresetEvents", dtype=unknown)
    preset_triggers = pvproperty_with_rbv(name="PresetTriggers", dtype=unknown)
    trace_data = pvproperty(name="TraceData", dtype=unknown)
    trace_mode = pvproperty_with_rbv(value="Mode", name="TraceMode", dtype=str)
    trace_time_array = pvproperty(name="TraceTimeArray", dtype=unknown)
    trace_time = pvproperty_with_rbv(name="TraceTime", dtype=unknown)


class McaDxpIOC(PVGroup):
    mca = SubGroup(EpicsMCAGroup, prefix="mca")
    dxp = SubGroup(EpicsDXPGroup, prefix="dxp:")


if __name__ == "__main__":
    ioc_options, run_options = ioc_arg_parser(
        default_prefix="test_mca:", desc="ophyd.tests.test_mca test IOC"
    )
    ioc = McaDxpIOC(**ioc_options)
    run(ioc.pvdb, **run_options)
