#pragma once

#include <fmt/core.h>

#ifndef FSM_DEBUG
#define FSM_STATE(C, S, E, ...) case C::S: S(E, ##__VA_ARGS__); break
#else
#define FSM_STATE(C, S, E, ...) case C::S: fmt::println(">> " #C " " #S " event={}, state={}", int(E), int($state)); S(E, ##__VA_ARGS__); fmt::println("<< " #C " state={}", int($state)); break
#endif

template<typename S, typename E>
class DeadSimpleFSM {
protected:
  // BUG: don't put this in your class because state() won't work
 S $state = S::START;

public:
  template<typename... Types>
  void event(E event, Types... args);

  void state(S next_state) {
    $state = next_state;
  }

  bool in_state(S state) {
    return $state == state;
  }
};