/*
 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
 *
 * This software is dual-licensed to you under the MIT License (MIT) and
 * the Universal Permissive License (UPL). See the LICENSE file in the root
 * directory for license terms. You may choose either license, or both.
 */

#include <string>
#include <stdexcept>
#include "iotcs_virtual_device.h"

#pragma once

/**
 * @brief A name-value pair in an event. Typically, the name is the name of
 * an attribute, and value is the attribute's value. But a name-value
 * pair could also be the name of a field in a format, or the name of
 * an action.
 * @param <T> the type of the value
 */
namespace iotdcl {
    class StorageObject;
    class NamedValue {
    public:
        /**
         * @brief Construct name-value pair from C Library structure.
         * @param <T> the type of the value
         * @throw std::invalid_argument
         */
        NamedValue(iotcs_named_value v) throw (std::invalid_argument);
        NamedValue(const NamedValue& v) throw (std::invalid_argument);
        virtual ~NamedValue();

        /**
         * @brief Get the next name-value pair in the event. This method
         * returns {@code null} if there are no more name-value pairs.
         * @return the next name-value pair, or {@code null}
         */
        NamedValue* next() const;

        /**
         * @brief Get the value.
         * @return the value
         */
        template <typename T> T getValue() const;

        /**
         * @brief Get the name.
         * @return the name
         */
        const std::string& getName() const;
    private:
        enum Type {Int, Number, String, Bool, DateTime, StorageObj};
        void checkType(Type) const;
        Type type;
        std::string name;
        iotcs_named_value value;
        StorageObject *so;
        NamedValue* m_next;
    };
};
