// Storm surge — inflow triples briefly, pumps should increase demand as
// the level enters the rising ramp.
//
// Expectation: during the surge (t=300..600), demand rises but remains
// bounded. High-volume safety should fire if the surge overwhelms pump
// capacity; dry-run should not fire.

module.exports = {
  name: 'levelbased-storm',
  description: 'Sewer inflow triples from 0.008 → 0.024 m³/s for 5 minutes then returns to baseline. High-volume safety may engage.',
  durationSec: 1500,

  config: {
    general: { name: 'EvalStorm', id: 'eval-storm', 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: 'levelbased',
      allowedModes: new Set(['levelbased']),
      levelbased: { minLevel: 1, startLevel: 2, maxLevel: 4, curveType: 'linear', logCurveFactor: 9 },
    },
    safety: {
      enableDryRunProtection: true,
      dryRunThresholdPercent: 2,
      enableHighVolumeSafety: true,
      highVolumeSafetyThresholdPercent: 95,
      timeleftToFullOrEmptyThresholdSeconds: 0,
    },
  },

  setup: async (ps) => {
    const MAX_OUTFLOW = 0.012;  // m³/s pumps cannot keep up with 3× surge
    ps.machineGroups['mgc1'] = {
      config: { general: { name: 'mgc1' } },
      turnOffAllMachines: () => {
        ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value(0, Date.now(), 'm3/s');
      },
      handleInput: async (_src, demand) => {
        const d = Math.max(0, Math.min(100, Number(demand) || 0));
        const outflow = (d / 100) * MAX_OUTFLOW;
        ps.measurements.type('flow').variant('predicted').position('out').child('mgc1').value(outflow, Date.now(), 'm3/s');
      },
    };
    ps.calibratePredictedLevel(2.5);
  },

  inputs: (t, ps) => {
    const surge = (t >= 300 && t < 600) ? 0.024 : 0.008;
    ps.setManualInflow(surge, Date.now(), 'm3/s');
  },

  expectations: [
    { name: 'dry-run never trips', type: 'end_state_eq', field: 'safetyActive', value: false },
    // Level may exceed maxLevel transiently but must stay under basinHeight
    { name: 'level never breaches physical basin', type: 'max_level_bounded', value: 5.0 },
    { name: 'demand remains bounded during surge', type: 'max_demand_bounded', value: 100 },
  ],
};
