/*
 * SPDX-FileCopyrightText: 2004 Copyright contributors to the cppTango project
 *
 * SPDX-License-Identifier: LGPL-3.0-or-later
 */

#include <tango/client/GroupCmdReply.h>

namespace Tango
{

//=============================================================================
// class GroupCmdReply : reply to command executed on a group
//=============================================================================
GroupCmdReply::GroupCmdReply()

{
    //-noop impl
}

//-----------------------------------------------------------------------------
GroupCmdReply::GroupCmdReply(const std::string &_dev_name,
                             const std::string &_obj_name,
                             const Tango::DeviceData &_dev_data) :
    GroupReply(_dev_name, _obj_name, true),
    data_m(_dev_data)
{
    //-noop impl
}

//-----------------------------------------------------------------------------
GroupCmdReply::GroupCmdReply(const std::string &_dev_name,
                             const std::string &_obj_name,
                             const Tango::DevFailed &_exception) :
    GroupReply(_dev_name, _obj_name, _exception, true)
{
    //-noop impl
}

//-----------------------------------------------------------------------------
GroupCmdReply::GroupCmdReply(const std::string &_dev_name, const std::string &_obj_name, bool group_element_enabled) :
    GroupReply(_dev_name, _obj_name, group_element_enabled)
{
    //-noop impl
}

GroupCmdReply::~GroupCmdReply() = default;

GroupCmdReply::GroupCmdReply(const GroupCmdReply &) = default;
GroupCmdReply &GroupCmdReply::operator=(const GroupCmdReply &) = default;

GroupCmdReply::GroupCmdReply(GroupCmdReply &&) = default;
GroupCmdReply &GroupCmdReply::operator=(GroupCmdReply &&) = default;

//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/*const*/ DeviceData &GroupCmdReply::get_data()
{
    if(!group_element_enabled_m && exception_enabled)
    {
        Tango::DevErrorList errors(1);
        errors.length(1);
        errors[0].severity = Tango::ERR;
        errors[0].desc = Tango::string_dup("no available data");
        errors[0].reason = Tango::string_dup("no data - group member is disabled");
        errors[0].origin = Tango::string_dup(TANGO_EXCEPTION_ORIGIN);
        DevFailed df(errors);
        throw df;
    }
    else if(has_failed_m && exception_enabled)
    {
        throw exception_m;
    }
    std::bitset<DeviceData::numFlags> bs;
    data_m.exceptions(exception_enabled ? bs.set() : bs.reset());
    return data_m;
}

//-----------------------------------------------------------------------------
bool GroupCmdReply::extract(std::vector<DevLong> &vl, std::vector<std::string> &vs)
{
    bool result = true;
    if(!group_element_enabled_m)
    {
        if(exception_enabled)
        {
            Tango::DevErrorList errors(1);
            errors.length(1);
            errors[0].severity = Tango::ERR;
            errors[0].desc = Tango::string_dup("no available data");
            errors[0].reason = Tango::string_dup("no data - group member is disabled");
            errors[0].origin = Tango::string_dup(TANGO_EXCEPTION_ORIGIN);
            DevFailed df(errors);
            throw df;
        }
        result = false;
    }
    else if(has_failed_m)
    {
        if(exception_enabled)
        {
            throw exception_m;
        }
        result = false;
    }
    else
    {
        std::bitset<DeviceData::numFlags> bs;
        data_m.exceptions(exception_enabled ? bs.set() : bs.reset());
        try
        {
            result = data_m.extract(vl, vs);
        }
        catch(const Tango::DevFailed &df)
        {
            exception_m = df;
            if(exception_enabled)
            {
                throw exception_m;
            }
            result = false;
        }
        catch(...)
        {
            if(exception_enabled)
            {
                Tango::DevErrorList errors(1);
                errors.length(1);
                errors[0].severity = Tango::ERR;
                errors[0].desc = Tango::string_dup("unknown exception caught");
                errors[0].reason = Tango::string_dup("an error occurred while trying to extract data");
                errors[0].origin = Tango::string_dup(TANGO_EXCEPTION_ORIGIN);
                DevFailed df(errors);
                exception_m = df;
                throw exception_m;
            }
            result = false;
        }
    }
    return result;
}

//-----------------------------------------------------------------------------
bool GroupCmdReply::extract(std::vector<double> &vd, std::vector<std::string> &vs)
{
    bool result = true;
    if(!group_element_enabled_m)
    {
        if(exception_enabled)
        {
            Tango::DevErrorList errors(1);
            errors.length(1);
            errors[0].severity = Tango::ERR;
            errors[0].desc = Tango::string_dup("no available data");
            errors[0].reason = Tango::string_dup("no data - group member is disabled");
            errors[0].origin = Tango::string_dup(TANGO_EXCEPTION_ORIGIN);
            DevFailed df(errors);
            throw df;
        }
        result = false;
    }
    else if(has_failed_m)
    {
        if(exception_enabled)
        {
            throw exception_m;
        }
        result = false;
    }
    else
    {
        std::bitset<DeviceData::numFlags> bs;
        data_m.exceptions(exception_enabled ? bs.set() : bs.reset());
        try
        {
            result = data_m.extract(vd, vs);
        }
        catch(const Tango::DevFailed &df)
        {
            exception_m = df;
            if(exception_enabled)
            {
                throw exception_m;
            }
            result = false;
        }
        catch(...)
        {
            if(exception_enabled)
            {
                Tango::DevErrorList errors(1);
                errors.length(1);
                errors[0].severity = Tango::ERR;
                errors[0].desc = Tango::string_dup("unknown exception caught");
                errors[0].reason = Tango::string_dup("an error occurred while trying to extract data");
                errors[0].origin = Tango::string_dup(TANGO_EXCEPTION_ORIGIN);
                DevFailed df(errors);
                exception_m = df;
                throw exception_m;
            }
            result = false;
        }
    }
    return result;
}

} // namespace Tango
