#pragma once

#include "sensor.h"
#include "switch.h"

#include <can-jf0815-hw.h>
#include <why-timer.h>
#include <why-spinlock.h>

#include <list>


class FSM
{
public:
    enum class State {
        INIT,
        RUNNING,
        OVERTEMP,
        SENSORBURNING,
    };

public:
    FSM(Why::TimeSpec interval,
        int sensor_burning_irq, Switch& hard_alarm,
        long soft_critical_temp, Switch& soft_alarm,
        int operator_button_irq,
        const std::string& can_iface,
        int can_id,
        Sensor& sensor, Switch& cooling,
        long low_temp, long high_temp);

    void start();

private:
    void _timer_tick();
    void _sensor_burning();
    void _operator_button_pressed();

    void _state_change(State state);                   // <-- instead of _state = ...
    void _can_xmit_done();                             // <-- ISR "can xmit buffer empty"

private:
    Why::Spinlock _lock;

    Why::TimeSpec _interval;
    Why::Timer _interval_timer;
    int _sensor_burning_irq;
    Switch& _hard_alarm;
    long _soft_critical_temp;
    Switch& _soft_alarm;
    int _operator_button_irq;
    Sensor& _sensor;
    Switch& _cooling;
    long _low_temp;
    long _high_temp;

    CAN_JF0815_HW _can_controller;                // <-- CAN controller
    int _can_id;                                       // <-- CAN application-id/bus-priority
    std::list<CANFrame> _pending_notifications;   // <-- queue frames until xmit not busy

    State _state;
};
