/* $Header: https://svn.mpia.de/gulli/TwiceAsNice/branch/unstable/ln/laos-drot/test/LaosDrotIntegrationTest_derotateTransitionChangeRelative_noRT.cc 14191 2017-03-01 19:21:03Z mathar $
*/

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE drotIntegrationTest

#include "Fixture.h"
#include <boost/test/unit_test.hpp>
#include <Basda/Mocca/PropertyName.h>
#include <Basda/Mocca/MPIA/PropertyName.h>
#include <Nice/Time/DateDummy.h>

volatile static int s_niceEnvironment = startSingletons("track_ctrl-svr.cfg");

struct DrotIntegrationFixture : public Fixture
{
        std::string m_moduleNode;

        DrotIntegrationFixture()
        {
            LOG_LEVEL(Nice::LERROR);
//            LOG_LEVEL(Nice::LWARNING);
//            LOG_LEVEL(Nice::LINFO);
//            LOG_LEVEL(Nice::LUSER9);
//            LOG_LEVEL(Nice::LDEBUG);


            std::string serviceName = s_app->config("DROT.SVC")->getAtNode<std::map<std::string, std::string> >("LOAD")["NAME"];
            m_drot = Basda::Basdard::service<Sharknir::DrotServiceWorkerInterface>(serviceName);
            I_LOG("change state to ONLINE")
            m_drot->changeState( Basda::ONLINE );
            I_LOG("wait for state ONLINE")
            m_drot->waitForState(Basda::ONLINE, Nice::Time::seconds(10));
            I_LOG("service is ONLINE")
        }

        virtual ~DrotIntegrationFixture()
        {
            // is empty because the open procedure fails with an exception
        }
};

BOOST_FIXTURE_TEST_SUITE( DrotIntegrationTest_derotateTransition_noRT, DrotIntegrationFixture )

BOOST_AUTO_TEST_CASE(checkderotateTransitionChangeRelative)
{
    // derotation starts at -1000 steps with a LBT trajectory with 60 polynomials
    // and a sampling rate of 1 second
    // check the config file lbcs.pangDummy-svc.cfg for these parameters!!
    // these trajectory moves about 526.177 steps
    std::string unit = "STEPS";

    int travelDuration = 60;    //seconds
    Nice::Time startDelay = Nice::Time::seconds(20);;        // seconds
    Nice::Time travelChangeAfter = Nice::Time::seconds(5.0);  // seconds
    Nice::Time travelChangeStart = Nice::Time::seconds(15); //seconds
    int travelDistance = 526;   // based on the LBT trajectory
    int travelShift = 100;
    int startPosition = -1000;

    Nice::DateDummyPtr niceDateDummy = Nice::DateDummy::init();

    double timelapse = 4;
    niceDateDummy->setTimelapse(timelapse);
    m_worker->setTimelapse(timelapse);

    BOOST_CHECK_NO_THROW(m_drot->moveToHome());
    BOOST_CHECK_NO_THROW(m_drot->moveAbsolute(startPosition, unit));
    BOOST_CHECK_EQUAL(m_drot->getPosition(), startPosition);

    Nice::Date startDate = Nice::Date::now() + startDelay;
    BOOST_CHECK_NO_THROW(m_drot->startDerotationStart(startDate , startPosition, unit));
    BOOST_CHECK_NO_THROW(m_drot->startDerotationWait(travelChangeAfter / timelapse));

    BOOST_CHECK_NO_THROW(m_drot->changeDerotationWithRelativeOffset(startDate + travelChangeStart, travelShift, unit));
    BOOST_CHECK_NO_THROW(m_drot->startDerotationWait());

    double position = m_worker->getDeviceEncoderPosition(unit);
    int finalPosition = startPosition + travelDistance / (travelDuration / travelChangeStart) + travelShift + travelDistance;
    BOOST_TEST_MESSAGE("expected position " << finalPosition << "; position reached " << position << " " << (552 / 100.0 * 10));
    BOOST_CHECK_CLOSE(position, finalPosition, (finalPosition / 100.0 * 5));
}

BOOST_AUTO_TEST_SUITE_END();
