/**
 * Combined integration test configuration.
 *
 * Exercises all components in the repo simultaneously:
 *   - SineArrayGAM   — array sine wave generation
 *   - TimeArrayGAM   — per-sample timestamp arrays
 *   - UDPStreamer     — UDPS wire protocol (ports 44500, 44501, 44502)
 *   - DebugService   — live signal tracing / forcing / breakpoints (ports 8080-8082)
 *     TcpLogger is auto-injected by DebugService on port 8082 (log port).
 *
 * Three real-time threads:
 *
 *   Thread1  1 kHz  — scalar signals → UDPStreamer port 44500 (Accumulate/multicast)
 *              Counter, Time, Sine1 (1 Hz), Sine2 (0.3 Hz)
 *
 *   Thread2  5 kHz  — packed arrays → UDPStreamer port 44501
 *              Ch1 float32[1000] @ 1 kHz   (TimeMode = FirstSample)
 *              Ch2 float32[1000] @ 10 kHz  (TimeMode = LastSample)
 *
 *   Thread3  5 kHz  — FullArray + explicit timestamps → UDPStreamer port 44502
 *              Ch3 float32[1000] @ 3 kHz   (TimeMode = FullArray)
 *              Ch4 float32[1000] @ 500 Hz  (TimeMode = FullArray)
 */

$App = {
    Class = RealTimeApplication

    +Functions = {
        Class = ReferenceContainer

        // ── Thread1: 1 kHz scalar signals ────────────────────────────────────

        +TimerGAM = {
            Class = IOGAM
            InputSignals = {
                Counter = {
                    DataSource = Timer
                    Type = uint32
                    Frequency = 1000
                }
                Time = {
                    DataSource = Timer
                    Type = uint32
                }
            }
            OutputSignals = {
                Counter = { DataSource = DDB1  Type = uint32 }
                Time    = { DataSource = DDB1  Type = uint32 }
            }
        }

        +SineGAM1 = {
            Class = SineArrayGAM
            Frequency    = 1.0
            Amplitude    = 5.0
            Phase        = 0.0
            Offset       = 0.0
            SamplingRate = 1000.0
            OutputSignals = {
                Sine1 = { DataSource = DDB1  Type = float32 }
            }
        }

        +SineGAM2 = {
            Class = SineArrayGAM
            Frequency    = 0.3
            Amplitude    = 3.0
            Phase        = 1.0472
            Offset       = 0.0
            SamplingRate = 1000.0
            OutputSignals = {
                Sine2 = { DataSource = DDB1  Type = float32 }
            }
        }

        +StreamerGAM1 = {
            Class = IOGAM
            InputSignals = {
                Counter = { DataSource = DDB1  Type = uint32  }
                Time    = { DataSource = DDB1  Type = uint32  }
                Sine1   = { DataSource = DDB1  Type = float32 }
                Sine2   = { DataSource = DDB1  Type = float32 }
            }
            OutputSignals = {
                Counter = { DataSource = Streamer1  Type = uint32  }
                Time    = { DataSource = Streamer1  Type = uint32  }
                Sine1   = { DataSource = Streamer1  Type = float32 }
                Sine2   = { DataSource = Streamer1  Type = float32 }
            }
        }

        // ── Thread2: 5 kHz packed arrays (FirstSample / LastSample) ──────────

        +FastTimerGAM = {
            Class = IOGAM
            InputSignals = {
                Time = {
                    DataSource = FastTimer
                    Type = uint32
                    Frequency = 5000
                }
            }
            OutputSignals = {
                Time = { DataSource = DDB2  Type = uint32 }
            }
        }

        +SineGAM3 = {
            Class = SineArrayGAM
            Frequency    = 1000.0
            Amplitude    = 1.0
            Phase        = 0.0
            Offset       = 0.0
            SamplingRate = 5000000.0
            OutputSignals = {
                Ch1 = {
                    DataSource = DDB2
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements   = 1000
                }
            }
        }

        +SineGAM4 = {
            Class = SineArrayGAM
            Frequency    = 10000.0
            Amplitude    = 0.5
            Phase        = 1.5708
            Offset       = 0.0
            SamplingRate = 5000000.0
            OutputSignals = {
                Ch2 = {
                    DataSource = DDB2
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements   = 1000
                }
            }
        }

        +StreamerGAM2 = {
            Class = IOGAM
            InputSignals = {
                Time = { DataSource = DDB2  Type = uint32  }
                Ch1  = { DataSource = DDB2  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch2  = { DataSource = DDB2  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
            }
            OutputSignals = {
                Time = { DataSource = Streamer2  Type = uint32  }
                Ch1  = { DataSource = Streamer2  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch2  = { DataSource = Streamer2  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
            }
        }

        // ── Thread3: 5 kHz FullArray with per-sample timestamps ──────────────

        +FullArrTimerGAM = {
            Class = IOGAM
            InputSignals = {
                Time = {
                    DataSource = FullArrTimer
                    Type = uint32
                    Frequency = 5000
                }
            }
            OutputSignals = {
                Time = { DataSource = DDB3  Type = uint32 }
            }
        }

        +SineGAM5 = {
            Class = SineArrayGAM
            Frequency    = 3000.0
            Amplitude    = 2.0
            Phase        = 0.0
            Offset       = 0.0
            SamplingRate = 5000000.0
            OutputSignals = {
                Ch3 = {
                    DataSource = DDB3
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements   = 1000
                }
            }
        }

        +SineGAM6 = {
            Class = SineArrayGAM
            Frequency    = 500.0
            Amplitude    = 3.0
            Phase        = 0.7854
            Offset       = 0.0
            SamplingRate = 5000000.0
            OutputSignals = {
                Ch4 = {
                    DataSource = DDB3
                    Type = float32
                    NumberOfDimensions = 1
                    NumberOfElements   = 1000
                }
            }
        }

        +TimeArrayGAM1 = {
            Class        = TimeArrayGAM
            SamplingRate = 5000000.0
            Anchor       = FirstSample
            InputSignals = {
                Time = { DataSource = DDB3  Type = uint32 }
            }
            OutputSignals = {
                TimeArray = {
                    DataSource = DDB3
                    Type = uint64
                    NumberOfDimensions = 1
                    NumberOfElements   = 1000
                }
            }
        }

        +StreamerGAM3 = {
            Class = IOGAM
            InputSignals = {
                TimeArray = { DataSource = DDB3  Type = uint64   NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch3       = { DataSource = DDB3  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch4       = { DataSource = DDB3  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
            }
            OutputSignals = {
                TimeArray = { DataSource = Streamer3  Type = uint64   NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch3       = { DataSource = Streamer3  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
                Ch4       = { DataSource = Streamer3  Type = float32  NumberOfDimensions = 1  NumberOfElements = 1000 }
            }
        }
    }

    +Data = {
        Class = ReferenceContainer
        DefaultDataSource = DDB1

        +DDB1 = { Class = GAMDataSource }
        +DDB2 = { Class = GAMDataSource }
        +DDB3 = { Class = GAMDataSource }

        // ── Timers (one per thread) ───────────────────────────────────────────
        +Timer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = { Type = uint32 }
                Time    = { Type = uint32 }
            }
        }

        +FastTimer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = { Type = uint32 }
                Time    = { Type = uint32 }
            }
        }

        +FullArrTimer = {
            Class = LinuxTimer
            SleepNature = "Default"
            Signals = {
                Counter = { Type = uint32 }
                Time    = { Type = uint32 }
            }
        }

        // ── UDPStreamer instances ─────────────────────────────────────────────

        // Thread1: scalar signals, Accumulate mode, multicast output
        +Streamer1 = {
            Class = UDPStreamer
            Port = 44500
            MulticastGroup = "239.0.0.1"
            DataPort = 44503
            MaxPayloadSize = 1400
            PublishingMode = "Accumulate"
            MinRefreshRate = 100
            Signals = {
                Counter = { Type = uint32 }
                Time    = { Type = uint32   Unit = "us" }
                Sine1   = { Type = float32  Unit = "V"  RangeMin = -5.0  RangeMax = 5.0 }
                Sine2   = { Type = float32  Unit = "V"  RangeMin = -3.0  RangeMax = 3.0 }
            }
        }

        // Thread2: packed arrays, FirstSample + LastSample
        +Streamer2 = {
            Class = UDPStreamer
            Port = 44501
            MaxPayloadSize = 1400
            Signals = {
                Time = { Type = uint32   Unit = "us" }
                Ch1  = {
                    Type = float32  Unit = "V"
                    NumberOfDimensions = 1  NumberOfElements = 1000
                    TimeMode = FirstSample  TimeSignal = Time  SamplingRate = 5000000.0
                }
                Ch2  = {
                    Type = float32  Unit = "V"
                    NumberOfDimensions = 1  NumberOfElements = 1000
                    TimeMode = LastSample   TimeSignal = Time  SamplingRate = 5000000.0
                }
            }
        }

        // Thread3: packed arrays, FullArray (per-sample timestamps)
        +Streamer3 = {
            Class = UDPStreamer
            Port = 44502
            MaxPayloadSize = 1400
            Signals = {
                TimeArray = {
                    Type = uint64  Unit = "ns"
                    NumberOfDimensions = 1  NumberOfElements = 1000
                }
                Ch3 = {
                    Type = float32  Unit = "V"
                    NumberOfDimensions = 1  NumberOfElements = 1000
                    TimeMode = FullArray  TimeSignal = TimeArray
                }
                Ch4 = {
                    Type = float32  Unit = "V"
                    NumberOfDimensions = 1  NumberOfElements = 1000
                    TimeMode = FullArray  TimeSignal = TimeArray
                }
            }
        }

        +Timings = { Class = TimingDataSource }
    }

    +States = {
        Class = ReferenceContainer
        +Running = {
            Class = RealTimeState
            +Threads = {
                Class = ReferenceContainer

                +Thread1 = {
                    Class = RealTimeThread
                    CPUs = 0x1
                    Functions = {TimerGAM SineGAM1 SineGAM2 StreamerGAM1}
                }

                +Thread2 = {
                    Class = RealTimeThread
                    CPUs = 0x2
                    Functions = {FastTimerGAM SineGAM3 SineGAM4 StreamerGAM2}
                }

                +Thread3 = {
                    Class = RealTimeThread
                    CPUs = 0x4
                    Functions = {FullArrTimerGAM SineGAM5 SineGAM6 TimeArrayGAM1 StreamerGAM3}
                }
            }
        }
    }

    +Scheduler = {
        Class = GAMScheduler
        TimingDataSource = Timings
    }
}

// ── DebugService ──────────────────────────────────────────────────────────────
// Patches the broker registry at startup so every signal is traceable.
// TcpLogger is auto-injected on LogPort (9090) — no explicit DataSource needed.
// Connect the debugger web UI (Client/debugger) to:
//   Host=127.0.0.1  TCP=8080  UDP=8081  Log=9090
+DebugService = {
    Class = DebugService
    ControlPort = 8080
    StreamPort  = 8081
    LogPort     = 9090
    StreamIP    = "127.0.0.1"
}
