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

#ifndef AXFLOGTASKINTERNAL_HPP_
#define AXFLOGTASKINTERNAL_HPP_

#include "AXFTask.hpp"
#include "AXFStage.hpp"

class AXFRingBufInternal;
class AXFCommRingBufInternal;

/**
 * @class AXFLogTaskInternal
 * @brief CPU間ログ転送用の送受信スレッド機能を提供する
 *
 * @n     ログ転送専用のスレッド・コンテキスト上でCPU間通信リング・バッファに対し、
 * @n     データの読み出し、書き込みを行う。
 */
class AXFLogTaskInternal {
  AXFRingBufInternal *m_sendBuf;
  AXFCommRingBufInternal *m_commBuf;
  AXFTask *m_thread;
  volatile bool m_run;

 public:

  /** @enum  logStatus
   *  @brief Log実行完了状態
   */
  enum logStatus {
    LOG_SUCCESS = 0,  ///< 正常終了
    LOG_ERROR,       ///< 異常終了
  };

#ifdef NEVER
  /** @enum  logRW
   *  @brief Logリード・ライト指定
   */
  enum logRW {
    LOG_READ = 0,  ///< リード指定
    LOG_WRITE,    ///< ライト指定
    LOG_RW_NUM    ///< 指定数
  };

  static logRW isRW;  ///< AXFLogTaskInternal リード・ライト指定
#endif

  /**
   * @brief AXFLogTaskInternalコンストラクタ
   */
  AXFLogTaskInternal(AXFRingBufInternal *sendBuf, AXFCommRingBufInternal *commBuf, AXFTask *thread)
      : m_sendBuf(sendBuf),
        m_commBuf(commBuf),
        m_thread(thread),
        m_run(false) {
  }

  /**
   * @brief AXFLogTaskInternalデストラクタ
   */
  virtual ~AXFLogTaskInternal() {
    delete m_sendBuf;
    delete m_commBuf;
    delete m_thread;
  }

  /*
   * @brief 初期化
   * @return AXFLogTaskInternal初期化状況
   * - LOG_SUCCESS 正常終了
   * - LOG_ERROR 異常終了
   */
  logStatus init();

  /*
   * @brief スレッド生成
   * @return AXFLogTaskInternalスレッド生成状況
   * - LOG_SUCCESS 正常終了
   * - LOG_ERROR 異常終了
   */
  logStatus create();

  /*
   * @brief スレッド終了
   * @return AXFLogTaskInternalスレッド終了状況
   * - LOG_SUCCESS 正常終了
   * - LOG_ERROR 異常終了
   */
  logStatus join();

  /**
   * @brief 書き込み
   * @param [in] data
   * @param [in] size
   * @return 書き込みデータサイズ(エラー時は 0 未満)
   */
  int write(char *data, int size);

 private:
  void* do_worker_sub();

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

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

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

#endif /* AXFLOGTASKINTERNAL_HPP_ */
