// Dry-run safety trip — manual mode, fixed high demand, zero inflow.
// Levelbased control would taper demand as the level drops (its ramp),
// stalling drainage before safety fires. Manual mode holds demand
// constant so the level actually reaches the dry-run threshold.

module.exports = {
  name: 'safety-dry-run-trip',
  description: 'Manual mode, constant 100 % demand, zero inflow; expect safety to force-stop downstream pumps when level reaches the dry-run threshold.',
  durationSec: 600,

  config: {
    general: { name: 'EvalDryRun', id: 'eval-dry-run', unit: 'm3/h',
      logging: { enabled: false, logLevel: 'error' } },
    functionality: { softwareType: 'pumpingStation', role: 'stationcontroller', positionVsParent: 'atEquipment' },
    basin: { volume: 50, height: 5, inflowLevel: 3, outflowLevel: 0.2, overflowLevel: 4.5, inletPipeDiameter: 0.4, outletPipeDiameter: 0.3 },
    hydraulics: { refHeight: 'NAP', basinBottomRef: 0, minHeightBasedOn: 'outlet' },
    control: {
      mode: 'manual',
      allowedModes: new Set(['levelbased', 'manual']),
      levelbased: { minLevel: 0.5, startLevel: 2, maxLevel: 4, curveType: 'linear', logCurveFactor: 9 },
    },
    safety: {
      enableDryRunProtection: true,
      dryRunThresholdPercent: 50,
      enableHighVolumeSafety: false,
      highVolumeSafetyThresholdPercent: 98,
      timeleftToFullOrEmptyThresholdSeconds: 0,
    },
  },

  setup: async (ps) => {
    const MAX_OUTFLOW = 0.04;
    let mgcRunning = true;  // gets toggled by safety's shutdown call
    ps.machineGroups['mgc1'] = {
      config: { general: { name: 'mgc1', id: 'mgc1' }, functionality: { positionVsParent: 'downstream' } },
      turnOffAllMachines: () => {
        mgcRunning = false;
        ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value(0, Date.now(), 'm3/s');
      },
      handleInput: async (_src, demand) => {
        if (!mgcRunning) return;
        const d = Math.max(0, Math.min(100, Number(demand) || 0));
        ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value((d / 100) * MAX_OUTFLOW, Date.now(), 'm3/s');
      },
    };
    // Need a downstream machine for safety to shut down
    ps.machines['pump1'] = {
      config: { general: { name: 'pump1', id: 'pump1' }, functionality: { positionVsParent: 'downstream' } },
      _isOperationalState: () => mgcRunning,
      handleInput: async (_src, action) => {
        if (action === 'execSequence') mgcRunning = false;
      },
    };
    ps.calibratePredictedLevel(2.5);
  },

  inputs: (t, ps) => {
    ps.setManualInflow(0, Date.now(), 'm3/s');
    if (ps.mode === 'manual') ps.forwardDemandToChildren(100);
  },

  expectations: [
    { name: 'safety engages at some point', type: 'safety_trips_gt', value: 0 },
    { name: 'level never goes below outflow pipe', type: 'min_level_bounded', value: 0.2 },
  ],
};
