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

#ifndef AXFSHELLINTERNAL_HPP_
#define AXFSHELLINTERNAL_HPP_

#include "AXFActor.hpp"
#include <vector>
#include <string>

/**
 * @class AXFShellInternal
 * @brief AXShell のフロントエンド機能を提供する
 *
 * @n     標準入力から入力された文字列をパースし、該当するアクタにAXメッセージを送信する。
 * @n
 * @n     AXライフサイクル・メソッドの 詳細は AXFActorクラス の説明に記述する。
 */
class AXFShellInternal : public AXFActor {
  AXFLog m_log;
  AXFObjectName& m_name;
  std::string* m_lastLine;
  std::vector<std::string> split(const std::string &str,
                                 const std::string &delim);
  AXFObjectName getDstName(std::vector<std::string>& cmdline, size_t stageIndex,
                           std::string& actorName, bool& isExistStage);

 public:

  /**
   * @brief  AXFShellInternalコンストラクタ
   */
  AXFShellInternal(AXFObjectName& name);

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

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

  // StateMachine用状態定義
  enum AXSHellState {
    STATE_STDIN = 0,
    STATE_MAX
  };

  // StateMachine用イベント定義
  enum AXShellEvent {
    EVENT_STDIN = AXFEVENT_MODEL(0), /* 標準入力 */
  };

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

  // StateMachine用メンバ関数宣言
  ax::actorFuncStatus funcStdin(const void *pParam, int size);

  // AXShell 標準コマンド・メソッド
  /**
   * @brief  AXShell Help コマンド処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdHelp(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell logon コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLogOn(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell logoff コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLogOff(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell log n コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLogLevel(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell logtranson コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLogTransOn(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell logtransoff コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLogTransOff(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell rinfo コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdRInfo(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell info コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdInfo(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell create コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdCreate(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell run コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdRun(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell runkeep コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdRunkeep(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell runscript コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdRunScript(std::vector<std::string>& cmdline);

#ifndef UNUSE_CHRONO	// baba Chrono非対応
  /**
   * @brief  AXShell setdate コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdSetDate(std::vector<std::string>& cmdline);
#endif	/* UNUSE_CHRONO */

  /**
   * @brief  AXShell tdon コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdTdOn(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell tdoff コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdTdOff(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell break コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdBreak(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell next コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdNext(std::vector<std::string>& cmdline);

#ifdef USE_LUA
  /**
   * @brief  AXShell luastr コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLuaStr(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell luafile コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdLuaFile(std::vector<std::string>& cmdline);
#endif /* USE_LUA */

  /**
   * @brief  AXShell quit コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdQuit(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell 拡張コマンド通知処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdExtend(std::vector<std::string>& cmdline);

  /**
   * @brief  AXShell コマンド解析処理
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  bool cmdParse(std::string& line);

  /**
   * @brief  AXShell 拡張コマンドメソッド型定義
   * @return
   * -    true：標準入力待ちにする
   * -    false：標準入力待ちにしない
   */
  typedef bool (AXFShellInternal::*cmdFunc)(std::vector<std::string>& cmdline);

  /**
   * @brief  AXshell 拡張コマンド・テーブル
   */
  struct stdCmdTable_t {
    const char* name;  ///> 拡張コマンド名
    bool (AXFShellInternal::*func)(std::vector<std::string>& cmdline);  ///> 拡張コマンド・メソッド
  };

  struct shellTable_t {
    const stdCmdTable_t* stdCmdTable;
  };

 private:
  struct shellTable_t m_shellTable;

  /**
   * @brief  日付と時刻の間を空白で入力されたとき、setdateコマンドパラメータを調整する
   */
  void adjustSetdateParam(std::vector<std::string>& cmdline, int& stageIndex);
};

#endif /* AXFSHELLINTERNAL_HPP_ */
