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

#ifndef TANGO_CLIENT_DBCLASS_H
#define TANGO_CLIENT_DBCLASS_H

#include <tango/client/DbDatum.h>

#include <memory>
#include <string>

/** @defgroup DBase Database Client classes
 * @ingroup Client
 */

namespace Tango
{
class Database;

/**********************************************************************
 *                                                                    *
 *  DbClass - A database object for accessing class related           *
 *               information in the database                          *
 *                                                                    *
 **********************************************************************/

/**
 * A database object for a class which can be used to query or modify class properties
 *
 * @headerfile tango.h
 * @ingroup DBase
 */
class DbClass
{
  private:
    std::string name;
    Database *dbase;
    int db_ind;
    bool ext_dbase;

    class DbClassExt
    {
      public:
        DbClassExt() { }
    };

    std::unique_ptr<DbClassExt> ext;

  public:
    /**@name Constructors */
    //@{
    /**
     * Create a DbClass instance.
     *
     * A constructor for a DbClass object for a class in the TANGO database specified by the TANGO_HOST
     * environment variable
     *
     * @param [in] class_name    The Tango class name
     *
     */
    DbClass(std::string class_name);
    /**
     * Create a DbClass instance using a specified database
     *
     * A constructor for a DbClass object for the Tango class in the specified database. This method reuses the
     * Database supplied by the programmer.
     *
     * @param [in] class_name    The Tango class name
     * @param [in] db The database object
     *
     */
    DbClass(std::string class_name, Database *db);
    //@}

    //
    // methods
    //
    /**@name Property oriented methods */
    //@{
    /**
     * Get class property from database
     *
     * Query the database for the list of properties of this class. See Database::get_class_property() for an example
     * of how to specify and retrieve the properties.
     *
     * @param [in,out] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void get_property(DbData &db);
    /**
     * Update class property in database
     *
     * Update the list of properties for this class in the database. See Database::put_class_property() for an example
     * of how to specify the properties.
     *
     * @param [in] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void put_property(const DbData &db);
    /**
     * Remove class property from database
     *
     * Delete the list of specified properties for this class in the database. See Database::delete_property() for an
     * example of how to specify the properties.
     *
     * @param [in] db Property name(s)
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void delete_property(const DbData &db);
    /**
     * Get class attribute property from database
     *
     * Query the database for the list of attribute properties of this class. See
     * Database::get_class_attribute_property() for an example of how to specify and retrieve the properties.
     *
     * @param [in,out] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void get_attribute_property(DbData &db);
    /**
     * Update class attribute property in database
     *
     * Update the list of attribute properties for this class in the database. See
     * Database::put_class_attribute_property() for an example of how to specify the properties.
     *
     * @param [in] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void put_attribute_property(const DbData &db);
    /**
     * Remove class attribute property from database
     *
     * Delete all properties for the list of specified attributes for this class in the database. See
     * Database::delete_class_attribute_property() for an example of how to specify the properties.
     *
     * @param [in] db Property name(s)
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void delete_attribute_property(const DbData &db);
    /**
     * Get class pipe property from database
     *
     * Query the database for the list of pipe properties of this class. See Database::get_class_pipe_property()
     * for an example of how to specify and retrieve the properties.
     *
     * @param [in,out] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void get_pipe_property(DbData &db);
    /**
     * Update class pipe property in database
     *
     * Update the list of pipe properties for this class in the database. See Database::put_class_pipe_property()
     * for an example of how to specify the properties.
     *
     * @param [in] db Property name(s) and value
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void put_pipe_property(const DbData &db);
    /**
     * Remove class pipe property from database
     *
     * Delete all properties for the list of specified pipes for this class in the database. See
     * Database::delete_class_pipe_property() for an example of how to specify the properties.
     *
     * @param [in] db Property name(s)
     *
     * @exception ConnectionFailed, CommunnicationFailed, DevFailed from device
     */
    void delete_pipe_property(const DbData &db);
    //@}

    /// @privatesection
    ~DbClass();
};
} // namespace Tango

#endif // TANGO_CLIENT_DBCLASS_H
