// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/DiagnosticRecordDispatcher.cpp 3765 2021-11-11 10:47:14Z depa $

// #include "basda/service/bcu/worker/DiagnosticRecordDispatcher.h"
#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/DiagnosticRecordDispatcher.h"

// #include "basda/service/bcu/worker/AdSecDiagnosticRecord.h"
// #include "basda/service/bcu/worker/ArgosBcuSlopeDiagnosticRecord.h"
// #include "basda/service/bcu/worker/ArgosBcuCcdDiagnosticRecord.h"

// #include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/AdSecDiagnosticRecord.h"
#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/SharknirBcuSlopeDiagnosticRecord.h"
#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/SharknirBcuCcdDiagnosticRecord.h"

#include "tiptilt_ctrl/bcu/util/Assertions.h"
// #include "util/SubversionId.h"
#include <Nice/Log.h>

#include <boost/static_assert.hpp>


namespace Sharknir
{
namespace Bcu
{


DiagnosticRecordDispatcher::DiagnosticRecordDispatcher(
        const std::string& name,
        const Basda::Microgate::DiagnosticRecordReceiverPtr& receiver,
        const OverallDiagnosticRecordBufferPtr& buffer) :
            receiver_(receiver), buffer_(buffer), name_(name)
{
    SHARKNIR_PRECONDITION(0 != receiver, "Receiver is valid.");
    SHARKNIR_PRECONDITION(0 != buffer, "Buffer is valid.");
}


void DiagnosticRecordDispatcher::dispatchOnce()
{
    BOOST_STATIC_ASSERT(sizeof(SharknirBcuSlopeDiagnosticRecord) !=
            sizeof(SharknirBcuCcdDiagnosticRecord));

    const Basda::Microgate::MasterBcuDiagnosticRecordPtr record=
            receiver_->getNextDiagnosticRecord();
    if (0 == record)
    {
        return;
    }
    const ByteBufferPtr rawRecord= record->getRawRecord();
    const size_t recordSizeInByte= rawRecord->size();

    if (recordSizeInByte == sizeof(SharknirBcuSlopeDiagnosticRecord))
    {
        dispatchSlopeRecord(rawRecord);
    }
    else if (recordSizeInByte == sizeof(SharknirBcuCcdDiagnosticRecord))
    {
        dispatchCcdRecord(rawRecord);
    }
    // else if (recordSizeInByte == sizeof(MirrorOutputDiagn))
    // {
    //     dispatchAsmRecord(rawRecord);
    // }
    else
    {
        W_LOG("Received unknown record: " << record->toString());
    }
}

std::string DiagnosticRecordDispatcher::name()
{
    return name_;
}

void DiagnosticRecordDispatcher::dispatchSlopeRecord(
        const ByteBufferPtr& rawRecord)
{
    const SharknirBcuSlopeDiagnosticRecord* const slopeRec=
            reinterpret_cast<SharknirBcuSlopeDiagnosticRecord*>(
                        &rawRecord->front());
    if (slopeRec->isBroken())
    {
        W_LOG("Discarding broken slope diagnostic record")
        return;
    }
    const FrameCounter fc= slopeRec->sc_HeaderDiag.dsc_FramesCounter;
    D_LOG("Dispatching slope record with framecounter " << fc)
    buffer_->insertSlopeRecord(fc, rawRecord);
}


void DiagnosticRecordDispatcher::dispatchCcdRecord(
        const ByteBufferPtr& rawRecord)
{
    const SharknirBcuCcdDiagnosticRecord* const ccdRec=
       reinterpret_cast<SharknirBcuCcdDiagnosticRecord*>(&rawRecord->front());
    const FrameCounter fc= ccdRec->header.dsc_FramesCounter;
    if (isCcdDiagnosticRecordBroken(ccdRec))
    {
        W_LOG("Discarding broken CCD diagnostic record with frame counter " <<
                fc);
        return;
    }
    D_LOG("Dispatching CCD record with framecounter " << fc);
    buffer_->insertCcdRecord(fc, rawRecord);
}


void DiagnosticRecordDispatcher::dispatchAsmRecord(
        const ByteBufferPtr& rawRecord)
{
    // does nothing since related to ASM.
    // TODO: act on SHARK-NIR DM?

    // const MirrorOutputDiagn* const diagn=
    //             reinterpret_cast<MirrorOutputDiagn*>(&rawRecord->front());
    // if (diagn->isBroken())
    // {
    //     W_LOG("Discarding broken ASM diagnostic record")
    //     return;
    // }
    // const FrameCounter fc= diagn->header.WFSFrameCounter;
    // D_LOG("Dispatching ASM record with framecounter " << fc)
    // buffer_->insertAsmRecord(fc, rawRecord);
}


}
}
