/*
 *******************************************************************************
 *
 *  Copyright 2026 RIEGL Laser Measurement Systems
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *  SPDX-License-Identifier: Apache-2.0
 *
 *******************************************************************************
 */
/*!
 *******************************************************************************
 *
 * \file    context.hpp
 * \author  RIEGL LMS GmbH, Austria
 * \brief   RDB library context
 * \version 2015-10-14/AW: Initial version
 * \version 2017-01-30/AW: Added function to check if a file is a RDB 2 file
 * \version 2017-11-24/AW: Constructors declared as "explicit" (#2825)
 * \version 2018-01-10/AW: Added friend class "pointcloud::Management"
 * \version 2020-06-29/AW: Database changelog interface added (#3614)
 * \version 2020-09-17/AW: Added function libraryFilename()
 *
 *******************************************************************************
 */

#ifndef RIEGL_RDB_CONTEXT_HPP
#define RIEGL_RDB_CONTEXT_HPP

//---< INCLUDES >---------------------------------------------------------------

#include <string>
#include <memory>

//---< NAMESPACE >--------------------------------------------------------------

namespace riegl {
namespace rdb {

//---< FORWARD DECLARATIONS >---------------------------------------------------

struct PointcloudData;

namespace pointcloud
{
    class CreateSettings;
    class OpenSettings;
    class PointAttributes;
    class PointAttribute;
    class QueryInsert;
    class QueryUpdate;
    class QueryRemove;
    class QueryInvert;
    class QueryFill;
    class Transaction;
    class Management;
    class Changelog;
}

//---< CLASS Context >----------------------------------------------------------
/*!
 * \brief Library context
 */
class Context
{
public:
    /*!
     * \brief Constructor
     *
     * Use _logPath_ to specify the target folder for RDB log files. If not
     * defined (empty string), then system's folder for temporary files is
     * used (i.e. Windows: "C:\Users\*\AppData\Local\Temp", Linux: "/tmp"). If
     * the given path does not exist, it is not created and logging is disabled.
     *
     * Use _logLevel_ to specify a filter for log messages. Allowed values are
     *
     *   | Level   | Description                |
     *   | ------- | -------------------------- |
     *   | TRACE   | many debug messages        |
     *   | DEBUG   | some debug messages        |
     *   | TEXT    | general messages = default |
     *   | INFO    | hints, information         |
     *   | WARNING | warning messages           |
     *   | ERROR   | error messages             |
     *   | FATAL   | fatal errors               |
     *   | NONE    | no log output at all       |
     *
     * Whereas "TRACE" is the highest log level and means to output everything
     * and "NONE" is the lowest level and means to output nothing. Example:
     * if _logLevel_ is set to "TEXT", debug messages are not output but info,
     * warnings, errors and fatal errors are.
     *
     * Both _logPath_ and _logLevel_ may also be given as environment variables
     * "RDB_LOG_PATH" and "RDB_LOG_LEVEL". Please note that those variables are
     * used only if empty strings are passed to the constructor.
     *
     * \note When the context is deleted, the log file is also deleted but
     *       only if it does not contain WARNING, ERROR or FATAL messages.
     *       To keep the context from deleting the log file, append "!" to
     *       the _logLevel_, e.g. "TEXT!".
     */
    explicit Context(
        const std::string &logLevel = "", //!< [in] log level (filter), see description
        const std::string &logPath  = ""  //!< [in] target folder for RDB log files
    );

    /*!
     * \brief Destructor
     */
    ~Context();

    /*!
     * \brief Returns library name
     */
    std::string libraryName() const;

    /*!
     * \brief Returns the name of the file the library was loaded from
     * \since 2.3.0
     */
    std::string libraryFilename() const;

    /*!
     * \brief Returns library version string
     */
    std::string libraryVersion() const;

    /*!
     * \brief Returns library license text
     */
    std::string libraryLicense() const;

    /*!
     * \brief Database file type title
     *
     * \returns "RDB 2 Database File"
     */
    std::string databaseFileTypeTitle() const;

    /*!
     * \brief Database file type suffix
     *
     * \returns "rdbx"
     */
    std::string databaseFileTypeSuffix() const;

    /*!
     * \brief Check file type
     *
     * \returns true if the given location is a RDB 2 database file.
     */
    bool databaseFileTypeCheck(const std::string &location) const;

private:
    struct Private;
    std::shared_ptr<Private> data;

    friend class  Logger;
    friend struct PointcloudData;
    friend class  pointcloud::CreateSettings;
    friend class  pointcloud::OpenSettings;
    friend class  pointcloud::PointAttributes;
    friend class  pointcloud::PointAttribute;
    friend class  pointcloud::QueryInsert;
    friend class  pointcloud::QueryUpdate;
    friend class  pointcloud::QueryRemove;
    friend class  pointcloud::QueryInvert;
    friend class  pointcloud::QueryFill;
    friend class  pointcloud::Transaction;
    friend class  pointcloud::Management;
    friend class  pointcloud::Changelog;
};

}} // namespace riegl::rdb

#endif // RIEGL_RDB_CONTEXT_HPP
