/**
 * @file   AXFDaemonInternal.hpp
 * @brief  AXFDaemonInternalクラスヘッダ
 *
 * @par    Programming Language
 *         C++
 */

#ifndef AXFDAEMONINTERNAL_HPP_
#define AXFDAEMONINTERNAL_HPP_

#include "AXConfig.hpp"
#include "AXFActor.hpp"
#include "AX.hpp"
#include "AXFStage.hpp"
#include "AXFTimeDomainInternal.hpp"

class AXFWatchdogInternal;
class AXFConditionVariableInternal;

/**
 * @class AXFDaemonInternal
 * @brief AXShellのバックエンド機能とStage内アクタの実行・監視制御機能を提供する
 *
 * @n     以下の機能を提供する。
 * @n     - AXShell のバックエンド
 * @n     - TimeDomainにおける、AXM層アクタの実行制御
 * @n     - Watchdog
 *
 * @n     AXライフサイクル・メソッドの 詳細は AXFActorクラス の説明に記述する。
 */
class AXFDaemonInternal : public AXFActor {
  AXFLog m_log;
  AXFObjectName& m_name;
  bool m_isCreatedAxm;
  bool m_isActiveAx;
  AX* m_ax;
  AXFStage *m_stage;
#ifndef	UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  AXFTimeDomainInternal* m_timeDomain;
#endif	/* UNUSE_CHRONO */
  AXFActor::TimerId_t m_tokenRingTimerID;  // タイマーID
  AXFWatchdogInternal* m_watchdog;
  AXFConditionVariableInternal* m_scriptCond;
  bool m_isScript;

#ifndef UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  bool enableTimeDomain();
  bool disableTimeDomain();
#endif

 public:
#ifdef	UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  /**
   * @brief  AXFDaemonInternalコンストラクタ
   */
  AXFDaemonInternal(AXFObjectName& name, AX* ax, AXFStage* stage,
                    AXFWatchdogInternal* watchdog,
                    AXFConditionVariableInternal* cond);
#else	/* UNUSE_CHRONO */
  /**
   * @brief  AXFDaemonInternalコンストラクタ
   */
  AXFDaemonInternal(AXFObjectName& name, AX* ax, AXFStage* stage,
                    AXFTimeDomainInternal* timeDomain,
                    AXFWatchdogInternal* watchdog,
                    AXFConditionVariableInternal* cond);
#endif	/* UNUSE_CHRONO */

  /**
   * @brief  AXFDaemonInternalデストラクタ
   */
  virtual ~AXFDaemonInternal();

  ax::actorFuncStatus onCreate();
  ax::actorFuncStatus onStart();
  ax::actorFuncStatus onStop();
#if 0
  ax::actorFuncStatus onPause();
  ax::actorFuncStatus onResume();
  ax::actorFuncStatus onRestart();
#endif
  ax::actorFuncStatus onDestroy();

  /**
   * @brief  StateMachine用状態定義
   */
  enum AXDaemonState {
    STATE_RUNNING = 0,
    STATE_MAX
  };

  /**
   * @brief  StateMachine用イベント定義
   */
  enum AXDaemonEvent {
    EVENT_CREATE_AXM = AXFEVENT_MODEL(1), /* AXM層アクタ・リソース生成 */
    EVENT_RUN_AX = AXFEVENT_MODEL(2), /* AX開始要求 */
    EVENT_QUIT_AX = AXFEVENT_MODEL(3), /* AX終了要求 */
    EVENT_LOG_ON = AXFEVENT_MODEL(4), /* Log出力 有効要求 */
    EVENT_LOG_OFF = AXFEVENT_MODEL(5), /* Log出力 無効要求 */
    EVENT_LOG_LEVEL = AXFEVENT_MODEL(6), /* Log出力レベル設定 要求 */
    EVENT_LOGTRANS_ON = AXFEVENT_MODEL(7), /* Log転送 有効要求 */
    EVENT_LOGTRANS_OFF = AXFEVENT_MODEL(8), /* Log転送 無効要求 */
    EVENT_RINFO = AXFEVENT_MODEL(9), /* アクタリソース情報出力 要求 */
    EVENT_INFO = AXFEVENT_MODEL(10), /* アクタ情報出力 要求 */
    EVENT_ENABLE_TIMEDOMAIN = AXFEVENT_MODEL(11), /* TimeDomain有効 */
    EVENT_DISABLE_TIMEDOMAIN = AXFEVENT_MODEL(12), /* TimeDomain無効 */
    EVENT_BREAK_INFO = AXFEVENT_MODEL(13), /* TimeDomain Break info指定 */
    EVENT_BREAK_ADD = AXFEVENT_MODEL(14), /* TimeDomain Break add指定 */
#ifndef UNUSE_CHRONO	// baba Chrono非対応
    EVENT_BREAK_SETDATE = AXFEVENT_MODEL(15), /* TimeDomain Break setdate指定 */
#endif	/* UNUSE_CHRONO */
    EVENT_BREAK_LIFECYCLE = AXFEVENT_MODEL(16), /* TimeDomain Break LifeCycle指定 */
    EVENT_BREAK_STATEMACHINE = AXFEVENT_MODEL(17), /* TimeDomain Break StateMachine指定 */
    EVENT_BREAK_DEL = AXFEVENT_MODEL(18), /* TimeDomain Break 削除 */
    EVENT_BREAK_FORCE = AXFEVENT_MODEL(19), /* TimeDomain 強制Break */
    EVENT_NEXT = AXFEVENT_MODEL(20), /* TimeDomain Next指定 */
#ifndef UNUSE_CHRONO	// baba Chrono非対応
    EVENT_SETDATE = AXFEVENT_MODEL(21), /* 時刻設定 要求 */
#endif	/* UNUSE_CHRONO */
    EVENT_RUNSCRIPT = AXFEVENT_MODEL(22), /* スクリプト実行要求 */
#ifdef USE_LUA
    EVENT_LUASTR = AXFEVENT_MODEL(23), /* Luaスクリプト文字列実行要求 */
    EVENT_LUAFILE = AXFEVENT_MODEL(24), /* Luaスクリプトファイル実行要求 */
#endif /* USE_LUA */
    EVENT_INTERVAL_TIMER = AXFEVENT_MODEL(25), /* 周期タイマ */
  };

  /**
   * @brief  Break addコマンドパラメータ定義
   */
  struct ParamBraekAdd {
    INT32_t breakTick;                                  ///< break更新tick
  };

#ifndef UNUSE_CHRONO	// baba Chrono非対応
  /**
   * @brief  Break setdateコマンドパラメータ定義
   */
  struct ParamBraekSetdate {
    AXFChrono::TimeSpec breakDate;                      ///< break指定時刻
  };
#endif	/* UNUSE_CHRONO */

  /**
   * @brief  Break lcコマンドパラメータ定義
   */
  struct ParamBraekLifeCycle {
    char fullActorName[AXCONFIG_FULLACTORNAME_MAXSIZE]; ///< アクタ名
    AXFActor::actorState state;                         ///< LifeCycle 状態値
  };

  /**
   * @brief  Break smコマンドパラメータ定義
   */
  struct ParamBraekStateMachine {
    char fullActorName[AXCONFIG_FULLACTORNAME_MAXSIZE]; ///< アクタ名
    INT32_t state;                                      ///< StateMachine 状態値
  };

  /**
   * @brief  Break delコマンドパラメータ定義
   */
  struct ParamBraekDel {
    INT32_t breakId;
  };

  /**
   * @brief  Break コマンドパラメータ定義
   */
  union ParamBreak {
    ParamBraekAdd add;                                  ///< addサブコマンド・パラメータ
#ifndef UNUSE_CHRONO	// baba Chrono非対応
    ParamBraekSetdate setdate;                          ///< setdateサブコマンド・パラメータ
#endif	/* UNUSE_CHRONO */
    ParamBraekLifeCycle lifeCycle;                      ///< lifeCycleサブコマンド・パラメータ
    ParamBraekStateMachine stateMachine;                ///< stateMachineサブコマンド・パラメータ
    ParamBraekDel del;                                  ///< delサブコマンド・パラメータ
  };

  /**
   * @brief  StateMachine用状態テーブル宣言
   */
  static const AXFDaemonInternal::StateTable stateRunning[];

  // StateMachine用メンバ関数宣言
  /**
   * @brief  AXShell create コマンド処理
   */
  ax::actorFuncStatus funcCreateAxm(const void *pParam, int size);

  /**
   * @brief  AXShell run コマンド処理
   */
  ax::actorFuncStatus funcRunAx(const void *pParam, int size);

  /**
   * @brief  AXShell quit コマンド処理
   */
  ax::actorFuncStatus funcQuitAx(const void *pParam, int size);

  /**
   * @brief  AXShell logon コマンド処理
   */
  ax::actorFuncStatus funcLogOn(const void *pParam, int size);

  /**
   * @brief  AXShell logoff コマンド処理
   */
  ax::actorFuncStatus funcLogOff(const void *pParam, int size);

  /**
   * @brief  AXShell log n コマンド処理
   */
  ax::actorFuncStatus funcLogLevel(const void *pParam, int size);

  /**
   * @brief  AXShell logtranson コマンド処理
   */
  ax::actorFuncStatus funcLogTransOn(const void *pParam, int size);

  /**
   * @brief  AXShell logtransoff コマンド処理
   */
  ax::actorFuncStatus funcLogTransOff(const void *pParam, int size);

  /**
   * @brief  AXShell rinfo コマンド処理
   */
  ax::actorFuncStatus funcRInfo(const void *pParam, int size);

  /**
   * @brief  AXShell info コマンド処理
   */
  ax::actorFuncStatus funcInfo(const void *pParam, int size);

#ifndef UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  /**
   * @brief  AXShell tdon コマンド処理
   */
  ax::actorFuncStatus funcEnableTimeDomain(const void *pParam, int size);

  /**
   * @brief  AXShell tdoff コマンド処理
   */
  ax::actorFuncStatus funcDisableTimeDomain(const void *pParam, int size);
#endif	/* UNUSE_CHRONO */

  /**
   * @brief  AXShell break infoコマンド処理
   */
  ax::actorFuncStatus funcBreakInfo(const void *pParam, int size);

  /**
   * @brief  AXShell break addコマンド処理
   */
  ax::actorFuncStatus funcBreakAdd(const void *pParam, int size);

#ifndef UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  /**
   * @brief  AXShell break setdateコマンド処理
   */
  ax::actorFuncStatus funcBreakSetdate(const void *pParam, int size);

  /**
   * @brief  AXShell break lcコマンド処理
   */
  ax::actorFuncStatus funcBreakLifecycle(const void *pParam, int size);

  /**
   * @brief  AXShell break smコマンド処理
   */
  ax::actorFuncStatus funcBreakStatemachine(const void *pParam, int size);

  /**
   * @brief  AXShell break delコマンド処理
   */
  ax::actorFuncStatus funcBreakDel(const void *pParam, int size);

  /**
   * @brief  AXShell break コマンド処理
   */
  ax::actorFuncStatus funcBreakForce(const void *pParam, int size);

  /**
   * @brief  AXShell next コマンド処理
   */
  ax::actorFuncStatus funcNext(const void *pParam, int size);

  /**
   * @brief  AXShell setdate コマンド処理
   */
  ax::actorFuncStatus funcSetDate(const void *pParam, int size);
#endif	/* UNUSE_CHRONO */
  /**
   * @brief  AXScript実行 コマンド処理
   */
  ax::actorFuncStatus funcRunScript(const void *pParam, int size);

#ifdef USE_LUA
  /**
   * @brief  Luaスクリプト文字列実行 コマンド処理
   */
  ax::actorFuncStatus funcLuaStr(const void *pParam, int size);

  /**
   * @brief  Luaスクリプトファイル実行 コマンド処理
   */
  ax::actorFuncStatus funcLuaFile(const void *pParam, int size);
#endif /* USE_LUA */

#ifndef UNUSE_CHRONO	// baba Chrono非対応のためAXFTimeDomainInternalは現状非対応
  /**
   * @brief  Watchdog 周期タイマ処理
   */
  ax::actorFuncStatus funcIntervalTimer(const void *pParam, int size);
#endif	/* UNUSE_CHRONO */

  /**
   * @brief  Watchdog 応答受信処理
   */
  ax::actorFuncStatus funcWatchdogAck(const void *pParam, int size);

  /**
   * @brief  AXScriptハンドラ実行完了通知処理
   */
  void scriptHandlerSignal();

  /**
   * @brief  AXScriptモード確認処理
   */
  bool isScriptMode();

 private:
  void runScript(struct axScript_t* script);
};

#endif /* AXFDAEMONINTERNAL_HPP_ */
