/*
 * AXFLogTaskInternal.cpp
 */

#include "AXFRingBufInternal.hpp"
#include "AXFCommRingBufInternal.hpp"
#include "AXFLogTaskInternal.hpp"
#include "AXFStdioInternal.hpp"
#include "AXFTimerInternal.hpp"

#include <iostream>
#include <string.h>

#ifdef USE_OUTPUT_RESULT_XML
#include "AXFScenarioTestInternal.hpp"
#endif /* USE_OUTPUT_RESULT_XML */

AXFLogTaskInternal::logStatus AXFLogTaskInternal::init() {
  AXFStage::logRW rw = AXFStage::isRW;
  if (rw == AXFStage::LOG_WRITE) {
  	if (m_sendBuf->init() != AXFRingBufInternal::RINGBUF_SUCCESS) return LOG_ERROR;
  }
  if (m_commBuf->init() != AXFCommRingBufInternal::RINGBUF_SUCCESS) return LOG_ERROR;
  return LOG_SUCCESS;
}

AXFLogTaskInternal::logStatus AXFLogTaskInternal::create() {
  AXFStage::logRW rw = AXFStage::isRW;
  struct {
    const char *name;
    AXFTask::taskPriority priority;
    size_t stackSize;
  } args[AXFStage::LOG_RW_NUM] = {
    {
      "logRecv",
      AXFTask::AXF_PRIORITY_LOW_1,
      4096,
    }, {
      "logSend",
      AXFTask::AXF_PRIORITY_LOW_2,
      2048,
    },
  };

  m_run = true;
  if (m_thread->create(
    args[rw].name,
    args[rw].priority,
    args[rw].stackSize,
    AXFLogTaskInternal::do_worker,
    this) != AXFTask::TASK_SUCCESS) {
      m_run = false;
      return LOG_ERROR;
  }
  return LOG_SUCCESS;
}

AXFLogTaskInternal::logStatus AXFLogTaskInternal::join() {
  AXFStage::logRW rw = AXFStage::isRW;
  m_run = false;

  if (rw == AXFStage::LOG_WRITE) {
    if (m_sendBuf->signalTo(AXFRingBufInternal::RINGBUF_READ) != AXFRingBufInternal::RINGBUF_SUCCESS) return LOG_ERROR;
  } else {
    if (m_commBuf->signalTo(AXFCommRingBufInternal::RINGBUF_READ) != AXFCommRingBufInternal::RINGBUF_SUCCESS) return LOG_ERROR;
  }
  m_thread->join();
  return LOG_SUCCESS;
}

int AXFLogTaskInternal::write(char *data, int size) {
  AXFStage::logRW rw = AXFStage::isRW;
  if (rw != AXFStage::LOG_WRITE) return -1;
  if (m_sendBuf->freeSize() < size) return 0; /* poi */
  return m_sendBuf->write(data, size);
}

void* AXFLogTaskInternal::do_worker_sub() {
  AXFStage::logRW rw = AXFStage::isRW;
  char buf[512];
  int n;

  AXFTimerInternal::maskTimerSignal();

  while (m_run) {
    if (rw == AXFStage::LOG_WRITE) {
      if ((n = m_sendBuf->read(buf, sizeof(buf))) < 0) continue;
      if (!m_run) break;
      if (m_commBuf->write(buf, n) != n) continue;
    } else {
      if ((n = m_commBuf->read(buf, sizeof(buf))) < 0) continue;
      if (!m_run) break;

      int i;
      for (i=0; i<n; i++) if (buf[i] == '\0') buf[i] = '\n';
      buf[n] = '\0';
#ifdef USE_OUTPUT_RESULT_XML
      AXFScenarioTestInternal::putOutputXML(
        AXFScenarioTestInternal::TYPE_AX_LOGTRANS, std::string(buf)); 
#endif /* USE_OUTPUT_RESULT_XML */
      AXFStdioInternal stdio;
      std::cout << buf;
      stdio.flush();
    }
  }
  if (m_thread) m_thread->exitSelf();
  //@UTIGN exitSelf
  return NULL;
}
