/*
 * SPDX-FileCopyrightText: 2025 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */
#include <tango/client/EventData.h>

#include <tango/internal/client/event_helpers.h>

#include <tango/client/DeviceAttribute.h>
#include <tango/server/tango_clock.h>

#include <chrono>

namespace Tango
{

//+----------------------------------------------------------------------
//
//     EventData constructor
//
//-----------------------------------------------------------------------

EventData::EventData(Tango::DeviceProxy *dev,
                     const std::string &nam,
                     const std::string &evt,
                     Tango::DeviceAttribute *attr_value_in,
                     Tango::EventReason event_reason_in,
                     const DevErrorList &errors_in) :
    device(dev),
    attr_name(nam),
    event(evt),
    attr_value(attr_value_in),
    event_reason(event_reason_in),
    errors(errors_in)
{
    TANGO_ASSERT(ensure_failure_reason_with_errors(event_reason, errors));

    err = errors.length() != 0;

    set_time();
}

//+----------------------------------------------------------------------
//
//     EventData copy constructor
//
//-----------------------------------------------------------------------

EventData::EventData(const EventData &sou)
{
    device = sou.device;
    attr_name = sou.attr_name;
    event = sou.event;
    if(sou.attr_value != nullptr)
    {
        attr_value = new DeviceAttribute(*(sou.attr_value));
    }
    else
    {
        attr_value = nullptr;
    }
    err = sou.err;
    errors = sou.errors;
    event_reason = sou.event_reason;
    reception_date = sou.reception_date;
}

//+----------------------------------------------------------------------
//
//     EventData assignement operator
//
//-----------------------------------------------------------------------

EventData &EventData::operator=(const EventData &ri)
{
    if(&ri == this)
    {
        return *this;
    }

    device = ri.device;
    attr_name = ri.attr_name;
    event = ri.event;
    if(ri.attr_value != nullptr)
    {
        delete attr_value;
        attr_value = new DeviceAttribute(*(ri.attr_value));
    }
    else
    {
        attr_value = nullptr;
    }
    err = ri.err;
    errors = ri.errors;
    event_reason = ri.event_reason;
    reception_date = ri.reception_date;

    return *this;
}

//+----------------------------------------------------------------------
//
//     EventData destructor
//
//-----------------------------------------------------------------------

EventData::~EventData()
{
    delete attr_value;
}

//+-----------------------------------------------------------------------
//
// method :
//        EventData::get_attr_err_info()
//
// description :
//        In case of Callback::push_event() error, the Callback's
//        DeviceAttribute member object attr_value is null. To make error
//        handling easier, this function returns a DeviceAttribute object
//        containing the error stack and event time.
//
// returns :
//        unique_ptr<DeviceAttribute> containing the Callback's error_stack.
//------------------------------------------------------------------------
std::unique_ptr<DeviceAttribute> EventData::get_attr_err_info()
{
    auto ptr = std::make_unique<DeviceAttribute>();
    DevErrorList *errCopy = new DevErrorList(errors);
    ptr->set_error_list(errCopy);
    ptr->name = attr_name;
    ptr->time = get_date();

    return ptr;
}

//+-------------------------------------------------------------------------
//
// method :         EventData::set_time
//
// description :     Set the event reception data
//
//--------------------------------------------------------------------------

void EventData::set_time()
{
    reception_date = make_TimeVal(std::chrono::system_clock::now());
}

} // namespace Tango
