/*
Copyright (c) 2017-2020,
Battelle Memorial Institute; Lawrence Livermore National Security, LLC; Alliance for Sustainable Energy, LLC.  See
the top-level NOTICE for additional details. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef HELICS_CPP98_PUBLICATION_HPP_
#define HELICS_CPP98_PUBLICATION_HPP_
#pragma once

#include "../shared_api_library/ValueFederate.h"
#include "helicsExceptions.hpp"

namespace helicscpp {
/** C++98 interface for a publication object*/
class Publication {
  public:
    /** construct from a helics_publication*/
    explicit Publication(helics_publication hpub) HELICS_NOTHROW: pub(hpub) {}
    /** default constructor*/
    Publication() HELICS_NOTHROW: pub(HELICS_NULL_POINTER){};
    /** copy constructor*/
    Publication(const Publication& publication): pub(publication.pub) {}
    /** copy assignment*/
    Publication& operator=(const Publication& publication)
    {
        pub = publication.pub;
        return *this;
    }
    // there is no need for move operators since copying the underlying object is fine, it is a non-owning pointer
    /** cast operator to the underlying helics_publication object*/
    operator helics_publication() const { return pub; }
    /** return the underlying helics_publication object*/
    helics_publication baseObject() const { return pub; }
    /** Methods to publish values **/

    /** publish raw data from a pointer and length*/
    void publish(const char* data, int len)
    {
        // returns helics_status
        helicsPublicationPublishRaw(pub, data, len, HELICS_IGNORE_ERROR);
    }
    /** publish a string from a char * */
    void publish(const char* str) { helicsPublicationPublishString(pub, str, HELICS_IGNORE_ERROR); }
    /** publish a string value*/
    void publish(const std::string& str)
    {
        helicsPublicationPublishString(pub, str.c_str(), HELICS_IGNORE_ERROR);
    }

    /** publish an int64_t value*/
    void publish(int64_t val)
    {
        // returns helics_status
        helicsPublicationPublishInteger(pub, val, HELICS_IGNORE_ERROR);
    }
    /** publish a double*/
    void publish(double val) { helicsPublicationPublishDouble(pub, val, HELICS_IGNORE_ERROR); }

    /** publish a complex number*/
    void publish(std::complex<double> cmplx)
    {
        helicsPublicationPublishComplex(pub, cmplx.real(), cmplx.imag(), HELICS_IGNORE_ERROR);
    }
    /** publish a vector of doubles*/
    void publish(const std::vector<double>& data)
    {
        helicsPublicationPublishVector(
            pub, data.data(), static_cast<int>(data.size() * sizeof(double)), HELICS_IGNORE_ERROR);
    }
    /** publish a named point with a string and double*/
    void publish(const std::string& name, double val)
    {
        helicsPublicationPublishNamedPoint(pub, name.c_str(), val, HELICS_IGNORE_ERROR);
    }
    /** publish a boolean value*/
    void publish(bool val)
    {
        helicsPublicationPublishBoolean(pub, val ? helics_true : helics_false, HELICS_IGNORE_ERROR);
    }
    /** get the key for the publication*/
    const char* getKey() const { return helicsPublicationGetKey(pub); }
    /** get the units of the publication*/
    const char* getUnits() const { return helicsPublicationGetUnits(pub); }
    /** get the type for the publication*/
    const char* getType() const { return helicsPublicationGetType(pub); }
    /** get the interface information field of the publication*/
    const char* getInfo() const { return helicsPublicationGetInfo(pub); }

    /** set the interface information field of the publication*/
    void setInfo(const std::string& info)
    {
        helicsPublicationSetInfo(pub, info.c_str(), HELICS_IGNORE_ERROR);
    }

  private:
    helics_publication pub; //!< the reference to the underlying publication
};

} // namespace helicscpp
#endif
