/**
 * SPDX-FileCopyrightText: 2024-2025 Open Mobile Platform LLC <community@omp.ru>
 * SPDX-License-Identifier: Proprietary
 */

#ifndef AURORA_APPLICATION_MC_LIB_CONFIGURATION_HPP
#define AURORA_APPLICATION_MC_LIB_CONFIGURATION_HPP

#include "global.hpp"

#include <QObject>
#include <QScopedPointer>
#include <QVariant>

namespace Aurora {

namespace Application {

namespace ManagedConfiguration {

class ConfigurationPrivate;

/**
 * @brief Application configuration class.
 * @class Configuration configuration.hpp <ManagedConfiguration/configuration.hpp>
 */
class AURORA_APPLICATION_MC_EXPORT Configuration
{
public:
    Configuration();
    Configuration(const Configuration &other);
    Configuration(Configuration &&other);
    virtual ~Configuration();

    Configuration &operator=(const Configuration &other);
    Configuration &operator=(Configuration &&other);

    /**
     * @brief Check if the \a key is contained in the configuration.
     *        Return \c false if value is not set for the \a key or the \a key does not exist.
     */
    bool containsKey(const QString &key) const;

    /**
     * @brief Check if the configuration contains any items.
     */
    bool isEmpty() const;

    /**
     *  @brief Return the value by \a key.
     *
     *  @return The type of the return value is the same as the type declared in the
     *          configuration file.
     *          Type matching:
     *          \li string -> \c QString
     *          \li integer -> \c int
     *          \li bool -> \c bool
     *          \li stringArray -> \c QStringList
     *          \li integerArray -> \c QList<int>
     *          \li boolArray -> \c QList<bool>
     *          \li select -> \c QString
     *          \li multiSelect -> \c QStringList
     *          \li structure -> Configuration
     */
    QVariant get(const QString &key) const;

    /**
     *  @brief Set the \a value for the \a key.
     *
     *  It is important that the \a value corresponds to the type declared
     *  in the configuration parameter file.
     *  Type matching:
     *  \li \c QString -> string
     *  \li \c int -> integer
     *  \li \c bool -> bool
     *  \li \c QStringList -> stringArray
     *  \li \c QList<int> -> integerArray
     *  \li \c QList<bool> -> boolArray
     *  \li \c QString -> select
     *  \li \c QStringList -> multiSelect
     *  \li Configuration -> structure
     */
    bool set(const QString &key, const QVariant &value);

    /**
     * @brief Return the configuration from a \c QVariant if it contains one,
     *        otherwise returns an empty configuration.
     */
    static Configuration fromVariant(const QVariant &value);

private:
    Configuration(ConfigurationPrivate *d);

    Q_DECLARE_PRIVATE(Configuration)
    QScopedPointer<ConfigurationPrivate> d_ptr;
};

} /* namespace ManagedConfiguration */

} /* namespace Application */

} /* namespace Aurora */

Q_DECLARE_METATYPE(Aurora::Application::ManagedConfiguration::Configuration);

#endif /* AURORA_APPLICATION_MC_LIB_CONFIGURATION_HPP */
