/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/* 
 * File:   iec61850_controller.cpp
 * Author: Jan Hudec
 * 
 * Created on 28. dubna 2019, 16:44
 */

#include <iostream>
#include "iec61850_controller.h"

iec61850_controller::iec61850_controller()
{
}

iec61850_controller::~iec61850_controller() {
    SVPublisher_destroy(this->_sv_pub);
}

void iec61850_controller::sv_publisher_create(CommParameters cp, std::string interface)
{
    char* tmp = strdup(interface.data());
    tmp[strlen(tmp) - 1] = '\0';
    
    this->_sv_pub = SVPublisher_create(&cp, tmp);
}

void iec61850_controller::sv_asdu_create(std::string name)
{
    SVPublisher_ASDU asdu = SVPublisher_addASDU(this->_sv_pub, name.c_str(), NULL, 1);
    
    this->_asdu_units.insert(std::pair<std::string, SVPublisher_ASDU>(name, asdu));
    this->_asdu_units_offsets[name] = {};
}

void iec61850_controller::sv_asdu_add_float(std::string name)
{
    this->_asdu_units_offsets[name].push_back(
        SVPublisher_ASDU_addFLOAT(this->_asdu_units[name])
    );
}

void iec61850_controller::sv_asdu_add_quality(std::string name)
{
    this->_asdu_units_offsets[name].push_back(
            SVPublisher_ASDU_addQuality(this->_asdu_units[name])
    );
}

void iec61850_controller::sv_asdu_add_timestamp(std::string name)
{
    this->_asdu_units_offsets[name].push_back(
        SVPublisher_ASDU_addTimestamp(this->_asdu_units[name])
    );
}

void iec61850_controller::sv_setup_complete()
{
    SVPublisher_setupComplete(this->_sv_pub);
}

void iec61850_controller::sv_asdu_set_float(std::string name, int offset_index, float value)
{
    SVPublisher_ASDU_setFLOAT(
            this->_asdu_units[name],
            this->_asdu_units_offsets[name][offset_index],
            value
    );
}

void iec61850_controller::sv_asdu_set_quality(std::string name, int offset_index, Quality quality)
{
    SVPublisher_ASDU_setQuality(
        this->_asdu_units[name],
        this->_asdu_units_offsets[name][offset_index],
        quality
    );
}

void iec61850_controller::sv_asdu_set_timestamp(std::string name, int offset_index, time_t ts)
{
    Timestamp_setTimeInSeconds(&this->_ts, ts);
    
    SVPublisher_ASDU_setTimestamp(
            this->_asdu_units[name],
            this->_asdu_units_offsets[name][offset_index],
            this->_ts
    );
}

void iec61850_controller::sv_publish()
{
    SVPublisher_publish(this->_sv_pub);
    
    std::map<std::string, SVPublisher_ASDU>::iterator it;
    for(it = this->_asdu_units.begin(); it != this->_asdu_units.end(); it++)
    {
        SVPublisher_ASDU_increaseSmpCnt(it->second);
    }
}