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

#ifndef TANGO_SERVER_WPIPE_H
#define TANGO_SERVER_WPIPE_H

#include <tango/server/Pipe.h>

#include <memory>
#include <string>
#include <vector>

namespace Tango
{

/**
 * This class is a class representing a writable pipe in the TANGO device server pattern. It is an base class.
 * It is the a root class for pipe related classes.
 *
 *
 * @headerfile tango.h
 * @ingroup Server
 */

class WPipe : public Pipe
{
  public:
    /**@name Constructors
     * Miscellaneous constructors */
    //@{
    /**
     * Constructs a newly allocated WPipe object.
     *
     * The default constructor
     */
    WPipe() :
        w_ext(new WPipeExt)
    {
    }

    /**
     * Constructs a newly allocated WPipe object from its
     * name, its description, its label and its display level
     *
     * @param     na        The pipe name
     * @param    level    The pipe display level
     *
     */
    WPipe(const std::string &_name, Tango::DispLevel level);

    //@}

    /**@name Destructor
     * Only one desctructor is defined for this class */
    //@{
    /**
     * The object desctructor.
     */
    ~WPipe() override { }

    //@}

    /**@name Get/Set methods.
     * Methods to get the value of the data blob transported by the pipe
     */
    //@{
    /**
     * Get root blob name
     *
     * Get the root blob name
     *
     * @return The root blob name
     */
    std::string get_root_blob_name()
    {
        return the_blob.get_name();
    }

//@}

/**@name Extracting data from a WPipe
 */
//@{
#ifdef GEN_DOC
    /**
     * Extract data from a device pipe
     *
     * Extracting data from a WPipe instance is simlar to extracting data from a DevicePipeBlob class instance.
     * See doc of DevicePipeBlob class extraction methods (DevicePipeBlob::operator>>) to get a complete documentation
     * on how to extract data from a WPipe
     *
     * @param [in] datum The pipe data
     * @exception WrongData if requested
     */
    WPipe &operator>>(short &datum);
#endif
    /**
     * Get root blob data element number
     *
     * Get the root blob data element number
     *
     * @return The root blob data element number
     */
    size_t get_data_elt_nb()
    {
        return the_blob.get_data_elt_nb();
    }

    /**
     * Get root blob data elements name
     *
     * Get the root blob data elements name
     *
     * @return The root blob data elements name
     */
    std::vector<std::string> get_data_elt_names()
    {
        return the_blob.get_data_elt_names();
    }

    /**
     * Get root blob data element name
     *
     * Get the root blob data element name for a single data element
     *
     * @param [in] ind The data element index within the root blob
     * @return The root blob data element name
     */
    std::string get_data_elt_name(size_t ind)
    {
        return the_blob.get_data_elt_name(ind);
    }

    /**
     * Get root blob data element value type
     *
     * Get the root blob data element value type for a single data element
     *
     * @param [in] ind The data element index within the root blob
     * @return The blob data element value type
     */
    int get_data_elt_type(size_t ind)
    {
        return the_blob.get_data_elt_type(ind);
    }

    //@}

    /// @privatesection
    virtual void write(DeviceImpl *) { }

    WPipe &operator[](const std::string &);

  private:
    class WPipeExt
    {
      public:
        WPipeExt() { }
    };

    std::unique_ptr<WPipeExt> w_ext; // Class extension
};

template <typename T>
WPipe &operator>>(WPipe &, T &);

template <typename T>
WPipe &operator>>(WPipe &, T *);

template <typename T>
WPipe &operator>>(WPipe &, DataElement<T> &);

} // namespace Tango

#endif // TANGO_SERVER_WPIPE_H
