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

#ifndef AXFCOMMRECEIVEINTERNAL_HPP_
#define AXFCOMMRECEIVEINTERNAL_HPP_

#include "AXFCommInternal.hpp"

class AXFTask;

/**
 * @class AXFCommReceiveInternal
 * @brief プロセス間・CPU間通信用の受信スレッド機能を提供する
 *
 * @n     受信専用のスレッド・コンテキスト上で受信データを共有メモリから読み出し、
 * @n     送信宛先に該当するアクタの Mailbox に転送する。
 */
class AXFCommReceiveInternal {
  AXFCommInternal* m_comm;
  AXFTask* m_thread;
  volatile bool m_isActive;
  char* m_rcvBuf;

 public:
  /** @enum  axcommReceiveStatus
   *  @brief axcommReceiveStatus実行完了状態
   */
  enum axcommReceiveStatus {
    AXCOMMRECEIVE_SUCCESS = 0,        ///< 正常終了
    AXCOMMRECEIVE_ERROR,              ///< 異常終了
    AXCOMMRECEIVE_ERROR_PARAM,        ///< 異常パラメータ
    AXCOMMRECEIVE_ERROR_NEW,          ///< new失敗
    AXCOMMRECEIVE_ERROR_INIT_AXCOMM,  ///< AXComm初期化エラー
    AXCOMMRECEIVE_ERROR_INIT_TASK,    ///< AXTask初期化エラー
  };

  /**
   * @brief AXFCommReceiveInternalコンストラクタ
   */
  AXFCommReceiveInternal(AXFCommInternal* comm, AXFTask* thread,
                         char* m_rcvBuf);

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

  /*
   * @brief 初期化
   * @param [in] type AXCommタイプ
   * @return AXFCommReceive初期化状況
   */
  axcommReceiveStatus init(AXComm_t type);

  /*
   * @brief 終了
   * @return AXFCommReceive終了状況
   */
  axcommReceiveStatus join();

  /**
   * @brief タスクにキャンセル要求する。
   */
  axcommReceiveStatus cancel();

 private:
  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.ASSIGN)
  AXFCommReceiveInternal& operator=(const AXFCommReceiveInternal&) {
    return *this;
  }

  // インスタンスのコピーは想定しない(Klockwork指摘対応:CL.FFM.COPY)
  AXFCommReceiveInternal(const AXFCommReceiveInternal& obj)
      : m_comm(obj.m_comm),
        m_thread(obj.m_thread),
        m_isActive(obj.m_isActive),
        m_rcvBuf(obj.m_rcvBuf) {
  }

  void *do_worker_sub();

  static void *do_worker(void *obj) {
    AXFCommReceiveInternal *fCommReceive =
        reinterpret_cast<AXFCommReceiveInternal *>(obj);
    return fCommReceive->do_worker_sub();
  }
};

#endif /* AXFCOMMRECEIVEINTERNAL_HPP_ */

