// ======================================================================
// \title  BufferAccumulatorTester.hpp
// \author bocchino, mereweth
// \brief  BufferAccumulator test harness implementation
//
// \copyright
// Copyright 2009-2017, by the California Institute of Technology.
// ALL RIGHTS RESERVED.  United States Government Sponsorship
// acknowledged.
//
// ======================================================================

#include "BufferAccumulatorTester.hpp"

#include "Fw/Types/BasicTypes.hpp"

#include "Fw/Types/MallocAllocator.hpp"

#define INSTANCE 0
#define MAX_HISTORY_SIZE 30
#define QUEUE_DEPTH 30

namespace Svc {

// ----------------------------------------------------------------------
// Construction and destruction
// ----------------------------------------------------------------------

BufferAccumulatorTester ::BufferAccumulatorTester(bool doAllocateQueue)
    :
#if FW_OBJECT_NAMES == 1
      BufferAccumulatorGTestBase("Tester", MAX_HISTORY_SIZE),
      component("BufferAccumulator"),
#else
      BufferAccumulatorGTestBase(MAX_HISTORY_SIZE),
      component(),
#endif
      doAllocateQueue(doAllocateQueue) {
  this->initComponents();
  this->connectPorts();

  // Witch to BufferAccumulator_OpState::DRAIN at start so we don't have to
  // change ut
  component.mode = BufferAccumulator_OpState::DRAIN;
  component.send = true;

  if (this->doAllocateQueue) {
    Fw::MallocAllocator buffAccumMallocator;
    this->component.allocateQueue(0, buffAccumMallocator, MAX_NUM_BUFFERS);
  }
}

BufferAccumulatorTester ::~BufferAccumulatorTester() {
  if (this->doAllocateQueue) {
    Fw::MallocAllocator buffAccumMallocator;
    this->component.deallocateQueue(buffAccumMallocator);
  }
}

// ----------------------------------------------------------------------
// Handlers for typed from ports
// ----------------------------------------------------------------------

void BufferAccumulatorTester ::from_bufferSendOutDrain_handler(const NATIVE_INT_TYPE portNum,
                                              Fw::Buffer& fwBuffer) {
  this->pushFromPortEntry_bufferSendOutDrain(fwBuffer);
}

void BufferAccumulatorTester ::from_bufferSendOutReturn_handler(const NATIVE_INT_TYPE portNum,
                                               Fw::Buffer& fwBuffer) {
  this->pushFromPortEntry_bufferSendOutReturn(fwBuffer);
}

void BufferAccumulatorTester ::from_pingOut_handler(const NATIVE_INT_TYPE portNum, U32 key) {
  this->pushFromPortEntry_pingOut(key);
}

// ----------------------------------------------------------------------
// Helper methods
// ----------------------------------------------------------------------

void BufferAccumulatorTester ::connectPorts() {
  // bufferSendInFill
  this->connect_to_bufferSendInFill(
      0, this->component.get_bufferSendInFill_InputPort(0));

  // bufferSendInReturn
  this->connect_to_bufferSendInReturn(
      0, this->component.get_bufferSendInReturn_InputPort(0));

  // cmdIn
  this->connect_to_cmdIn(0, this->component.get_cmdIn_InputPort(0));

  // pingIn
  this->connect_to_pingIn(0, this->component.get_pingIn_InputPort(0));

  // bufferSendOutDrain
  this->component.set_bufferSendOutDrain_OutputPort(
      0, this->get_from_bufferSendOutDrain(0));

  // bufferSendOutReturn
  this->component.set_bufferSendOutReturn_OutputPort(
      0, this->get_from_bufferSendOutReturn(0));

  // cmdRegOut
  this->component.set_cmdRegOut_OutputPort(0, this->get_from_cmdRegOut(0));

  // cmdResponseOut
  this->component.set_cmdResponseOut_OutputPort(
      0, this->get_from_cmdResponseOut(0));

  // eventOut
  this->component.set_eventOut_OutputPort(0, this->get_from_eventOut(0));

  // eventOutText
  this->component.set_eventOutText_OutputPort(0,
                                              this->get_from_eventOutText(0));
  // pingOut
  this->component.set_pingOut_OutputPort(0, this->get_from_pingOut(0));

  // timeCaller
  this->component.set_timeCaller_OutputPort(0, this->get_from_timeCaller(0));

  // tlmOut
  this->component.set_tlmOut_OutputPort(0, this->get_from_tlmOut(0));
}

void BufferAccumulatorTester ::initComponents() {
  this->init();
  this->component.init(QUEUE_DEPTH, INSTANCE);
}

}  // end namespace Svc
