// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/FakeDevice.h 1160 2019-01-24 16:30:31Z depa $
#pragma once

#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/PropertyName.h"
#include "tiptilt_ctrl/bcu/Interface/Sharknir/Bcu/Device.h"

#include <Nice/Property/Joint.h>

#include "tiptilt_ctrl/bcu/util/C++11.h"



namespace Sharknir { namespace Bcu {

class FakeDeviceException: public Nice::Exception
{
};


class FakeDevice : public Device
{
public:
    FakeDevice(const Nice::JointPtr& config) : config_(config)
    {
        assert(config);
    	if (! config_->exist(PropertyName::Simulator::failureRequested()))
        {
    		config_->setAtNode<bool>(
    		    PropertyName::Simulator::failureRequested(), false);
        }
    }

    virtual double readBcuFpgaTemperatureInC() override
    {
    	throwExceptionIfRequested();
        return config_->getWithDefault<double>(
            PropertyName::Simulator::bcuFpgaSetTemperature(), 0);
    }

    virtual double readBcuPcbTemperatureInC() override
    {
    	throwExceptionIfRequested();
        return 0;
    }

    // virtual double readDsp16do0FpgaTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readDsp16do0PcbTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readDsp16do1FpgaTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readDsp16do1PcbTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readHvc0FpgaTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readHvc0PcbTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readHvc1FpgaTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    // virtual double readHvc1PcbTemperatureInC() override
    // {
    // 	throwExceptionIfRequested();
    //     return 0;
    // }

    virtual Basda::Microgate::MemoryBufferPtr read(
            Basda::Microgate::OpCode /* opcode */,
            uint8_t /* firstDspIndex */,
            uint8_t /* lastDspIndex */,
            int32_t /* address */,
            unsigned lengthInDword) override
    {
    	throwExceptionIfRequested();

        return Basda::Microgate::MemoryBuffer::create(lengthInDword);
    }

    virtual void write(Basda::Microgate::OpCode /* opcode */,
                       uint8_t /* firstDsp */,
                       uint8_t /* lastDsp */,
                       int32_t /* address */,
                       const Basda::Microgate::MemoryBufferPtr& /* buffer */)
                           override
    {
    	throwExceptionIfRequested();
    }

    virtual void uploadDspCode(Nice::U8 /* firstDsp */,
                               Nice::U8 /* lastDsp */,
                               const Nice::File& /* dspProgram */) override
   {
    	throwExceptionIfRequested();
   }

    virtual void enableMasterDiagnostics(Nice::U16 /* decimationFactor */,
            const std::string& /* remoteIpv4Address */,
            const std::string& /* remoteMacAddress */,
            Nice::U16  /* remoteUdpPortNr */) override
    {
    	throwExceptionIfRequested();
    }

private:
    void throwExceptionIfRequested()
    {
    	using Sharknir::Bcu::PropertyName;
    	if (config_->getWithDefault<bool>(
    	    PropertyName::Simulator::failureRequested(), false))
    	{
    		E_THROW(FakeDeviceException, "This failure is requested");
    	}
    }

    Nice::JointPtr config_;
};

}
}
