class ProcessingConfig(configbase.ProcessingConfig):
    VERSION = 1

    class BackgroundMode(Enum):
        SUBTRACT = "Subtract"
        LIMIT = "Limit"

    show_peak_depths = configbase.BoolParameter(
        label="Show peak distances",
        default_value=True,
        updateable=True,
        order=-10,
    )

    bg_buffer_length = configbase.IntParameter(
        default_value=50,
        limits=(1, 200),
        label="Background buffer length",
        order=0,
    )

    bg = configbase.ReferenceDataParameter(
        label="Background",
        order=10,
    )

    bg_mode = configbase.EnumParameter(
        label="Background mode",
        default_value=BackgroundMode.SUBTRACT,
        enum=BackgroundMode,
        updateable=True,
        order=20,
    )

    history_length = configbase.IntParameter(
        default_value=100,
        limits=(10, 1000),
        label="History length",
        order=30,
    )
class ProcessingConfiguration(configbase.ProcessingConfig):
    class ThresholdType(Enum):
        FIXED = "Fixed"
        RECORDED = "Recorded"
        CFAR = "CFAR"

    class PeakSorting(Enum):
        STRONGEST = "Strongest signal"
        CLOSEST = "Closest signal"
        STRONGEST_REFLECTOR = "Strongest reflector"
        STRONGEST_FLAT_REFLECTOR = "Strongest flat reflector"

    VERSION = 1

    nbr_average = configbase.FloatParameter(
        label="Sweep averaging",
        default_value=5,
        limits=(1, 100),
        logscale=True,
        decimals=0,
        updateable=True,
        order=0,
        visible=True,
        help=(
            "The number of envelope sweeps to be average into one then used for"
            " distance detection."),
    )

    threshold_type = configbase.EnumParameter(
        label="Threshold type",
        default_value=ThresholdType.FIXED,
        enum=ThresholdType,
        updateable=True,
        order=5,
        help="Setting the type of threshold",
    )

    fixed_threshold = configbase.FloatParameter(
        label="Fixed threshold level",
        default_value=800,
        limits=(1, 20000),
        decimals=0,
        updateable=True,
        order=10,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.FIXED,
        help=
        ("Sets the value of fixed threshold. The threshold has this constant value over"
         " the full sweep."),
    )

    sc_nbr_sweep_for_bg = configbase.FloatParameter(
        label="Number of sweeps for background estimation",
        default_value=20,
        limits=(2, 200),
        decimals=0,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.
        RECORDED,
        updateable=True,
        order=20,
        help=
        ("The number of (non-averaged) sweeps collected for calculating the Stationary"
         " Clutter threshold."),
    )

    sc_load_save_bg = configbase.ReferenceDataParameter(
        label="Recorded threshold",
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.
        RECORDED,
        order=23,
        help=("Load/Save a recorded threshold from/to disk."),
    )

    sc_sensitivity = configbase.FloatParameter(
        label="Stationary clutter sensitivity",
        default_value=0.3,
        limits=(0.01, 1),
        logscale=True,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.
        RECORDED,
        decimals=4,
        updateable=True,
        order=24,
        help=
        ("Value between 0 and 1 that sets the threshold. A low sensitivity will set a "
         "high threshold, resulting in only few false alarms but might result in "
         "missed detections."),
    )

    cfar_sensitivity = configbase.FloatParameter(
        label="CFAR sensitivity",
        default_value=0.5,
        limits=(0.01, 1),
        logscale=True,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.CFAR,
        decimals=4,
        updateable=True,
        order=40,
        help=
        ("Value between 0 and 1 that sets the threshold. A low sensitivity will set a "
         "high threshold, resulting in only few false alarms but might result in "
         "missed detections."),
    )

    cfar_guard_cm = configbase.FloatParameter(
        label="CFAR guard",
        default_value=12,
        limits=(1, 20),
        unit="cm",
        decimals=1,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.CFAR,
        updateable=True,
        order=41,
        help=
        ("Range around the distance of interest that is omitted when calculating "
         "CFAR threshold. Can be low, ~4 cm, for Profile 1, and should be "
         "increased for higher Profiles."),
    )

    cfar_window_cm = configbase.FloatParameter(
        label="CFAR window",
        default_value=3,
        limits=(0.1, 20),
        unit="cm",
        decimals=1,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.CFAR,
        updateable=True,
        order=42,
        help=
        ("Range next to the CFAR guard from which the threshold level will be calculated."
         ),
    )

    cfar_one_sided = configbase.BoolParameter(
        label="Use only lower distance to set threshold",
        default_value=False,
        visible=lambda conf: conf.threshold_type == conf.ThresholdType.CFAR,
        updateable=True,
        order=43,
        help=
        ("Instead of determining the CFAR threshold from sweep amplitudes from "
         "distances both closer and a farther, use only closer. Helpful e.g. for "
         "fluid level in small tanks, where many multipath signal can apprear "
         "just after the main peak."),
    )

    peak_sorting_type = configbase.EnumParameter(
        label="Peak sorting",
        default_value=PeakSorting.STRONGEST,
        enum=PeakSorting,
        updateable=True,
        order=100,
        help="Setting the type of peak sorting method.",
    )

    history_length_s = configbase.FloatParameter(
        default_value=10,
        limits=(3, 1000),
        updateable=True,
        logscale=True,
        unit="s",
        label="History length",
        order=198,
        help="Length of time history for plotting.")

    show_first_above_threshold = configbase.BoolParameter(
        label="Show first distance above threshold",
        default_value=False,
        updateable=True,
        order=199,
        help=
        ("When detect in the presence of object very close to the sensor, the "
         "strong direct leakage might cause that no well shaped peaks are detected, "
         "even though the envelope signal is above the threshold. Therefore the "
         "first distace where the signal is above the threshold can be used as an "
         "alternative to peak detection."),
    )

    def check_sensor_config(self, sensor_config):
        alerts = []

        if sensor_config.update_rate is None:
            alerts.append(configbase.Error("update_rate", "Must be set"))

        if not sensor_config.noise_level_normalization:
            if self.threshold_type == self.ThresholdType.FIXED:
                alerts.append(
                    configbase.Warning(
                        "noise_level_normalization",
                        ("Enabling noise level normalization is "
                         "recommended with Fixed threshold")))

        return alerts