//
// Created by magino on 6.6.19.
//

#ifndef ICOMMUNICATION_H
#define ICOMMUNICATION_H

#include <open62541/types.h>

class ICommunication {
private:
    virtual int GetCycleTime() = 0;
protected:
public:
    /**
     * Reads new value from synchronized data.
     * @param params Parameters are different for each implementation of communication. For example Modbus TCP needs number of modbus register.
     * @return Value addressed by params.
     */
    virtual UA_Variant ReadValue(void* params) = 0;
    /**
     * Writing new data to device.
     * @param data Generic data to write
     * @param params Parameters are different for each implementation of communication. For example Modbus TCP needs number of modbus register.
     */
    virtual void WriteValue(UA_Variant data, void* params) = 0;

    /**
     * Connect/Reconnect communication.
     * @param running
     */
    virtual void Reconnect(volatile bool* running) = 0;
    /**
     * Synchronize all data with device.
     */
    virtual void GetData() = 0;
    virtual void StopComm() = 0;

    void StartComm(volatile bool* running) {

        // Init variables
        unsigned int elapsed, sleep_time;
        Reconnect(running);

        while(*running) {
            // Start time
            auto start = std::chrono::steady_clock::now();

            // Gather Data
            GetData();

            // Calculate Sleep Time
            elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - start).count();

            //std::cout << "Elapsed time: " << elapsed <<  " Cycle: "<<  ++cycle_count << " Time:" << std::chrono::system_clock::to_time_t(std::chrono::system_clock::now()) << std::endl;
            if(elapsed < GetCycleTime()) {
                sleep_time = (GetCycleTime() - elapsed)*1000;
                //std::cout << "Sleep time: " << sleep_time << std::endl;
                usleep(sleep_time);
            }
        }
        StopComm();
        std::cout << "COMMUNICATION CYCLE END" << std::endl;
    }
};
#endif //ICOMMUNICATION_H