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

#ifndef TANGO_SERVER_FWDATTR_H
#define TANGO_SERVER_FWDATTR_H

#include <tango/server/Attr.h>
#include <tango/server/ImageAttr.h>
#include <tango/server/SpectrumAttr.h>
#include <tango/server/UserDefaultAttrProp.h>
#include <tango/server/UserDefaultFwdAttrProp.h>

#include <memory>
#include <string>

namespace Tango
{
class AttrConfEventData;
class MultiAttribute;

/**
 * User class to create a forwarded attribute object.
 *
 * Information from this class and information fetched out from the Tango
 * database allows the Tango core software to create the FwdAttribute object
 * for the forwarded attribute created by the user.
 *
 *
 * @headerfile tango.h
 * @ingroup Server
 */

class FwdAttr : public ImageAttr
{
  public:
    /**@name Constructors
     * Only one constructor is defined for this class */
    //@{
    /**
     * Constructs a newly allocated FwdAttr object.
     *
     * @param     name    The attribute name
     * @param    root_attribute    The root attribute name (FQAN)
     *
     */
    FwdAttr(const std::string &name, const std::string &root_attribute = RootAttNotDef);
    //@}

    /**@name Miscellaneous methods*/
    //@{
    /**
     * Set default attribute properties
     *
     * @param    prop    The user default property class
     */
    void set_default_properties(UserDefaultFwdAttrProp &prop);
    //@}

    /// @privatesection
    FwdAttr(const FwdAttr &);

    bool is_fwd() override
    {
        return true;
    }

    std::string &get_fwd_root_att()
    {
        return fwd_root_att;
    }

    std::string &get_fwd_dev_name()
    {
        return fwd_dev_name;
    }

    std::string &get_full_root_att()
    {
        return full_root_att;
    }

    bool is_correctly_configured()
    {
        return fwd_wrongly_conf;
    }

    FwdAttError get_err_kind()
    {
        return err_kind;
    }

    void set_err_kind(FwdAttError _e)
    {
        err_kind = _e;
    }

    void read(DeviceImpl *, Attribute &) override;
    void write(DeviceImpl *, WAttribute &) override;

    bool is_allowed(DeviceImpl *, AttReqType) override
    {
        return true;
    }

    virtual void init_conf(AttrConfEventData *);
    bool validate_fwd_att(std::vector<AttrProperty> &, const std::string &);
    void get_root_conf(const std::string &, DeviceImpl *);

    void remove_useless_prop(std::vector<AttrProperty> &, const std::string &, MultiAttribute *);
    std::string &get_label_from_default_properties();

  protected:
    /// @privatesection
    std::string full_root_att; // Root att (dev_name/att_name)
    std::string fwd_dev_name;  // Root att device name (lower case)
    std::string fwd_root_att;  // Root att (lower case)
    bool fwd_wrongly_conf{false};
    FwdAttError err_kind{FWD_ERR_UNKNOWN};

  private:
    class FwdAttrExt
    {
    };

    std::unique_ptr<FwdAttrExt> ext; // Class extension
};

} // namespace Tango

#endif /* _FWDATTR_H */
