/*
 *******************************************************************************
 *
 *  Copyright 2025 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    rdb-example-09-cleanup-database.cpp
 * \author  RIEGL LMS GmbH, Austria
 * \brief   RDB example 9: Cleanup database
 * \version 2017-01-30/AW: Initial version
 * \version 2018-07-10/AW: Better error handling
 *
 *  This example shows how to open an existing database and how to dismiss
 *  the database history, i.e. to delete all transactions except the first
 *  (database creation) and the current transaction (last committed or
 *  restored).
 *
 *  Afterwards we vacuum the database which reorganizes the data blocks in
 *  the database file so that there are no (or as few as possible) unused
 *  blocks (gaps).
 *
 *  Please note, that both database operations cannot be reverted!
 *
 *  Build instructions see "interface/cpp/riegl/README.TXT".
 *
 *******************************************************************************
 */

#include <cstdint>
#include <iostream>
#include <exception>

#include <riegl/rdb.hpp>

int main()
{
    try
    {
        // New RDB library context
        riegl::rdb::Context context;

        // Access existing database
        riegl::rdb::Pointcloud rdb(context);
        riegl::rdb::pointcloud::OpenSettings settings;
        rdb.open("pointcloud.rdbx", settings);

        // First we delete the history (see comments in header)
        rdb.management().finalize();

        //____________________________________________________________________//
        //                                                                    //
        //   At this point, there might be many unused data blocks in the     //
        //   database file which were occupied by the transactions we have    //
        //   just deleted. These data blocks will be re-used when we create   //
        //   new transactions to insert, update or remove points or make      //
        //   other changes to e.g. meta data items.                           //
        //   So the following vacuum step is optional but might be a good     //
        //   idea before archiving or transferring the database file.         //
        //____________________________________________________________________//
        //                                                                    //

        // Now we reorganize and shrink the database file:
        rdb.management().vacuum(
            [](const uint8_t progress)
            {
                // As this might be a lengthy operation, vacuum() accepts
                // an optional callback function to notify the user about
                // the (coarse) progress. However there is no function to
                // cancel this process.
                std::cout << "progress: " << int(progress) << "%" << std::endl;
            }
        );

        // Success
        return 0;
    }
    catch(const riegl::rdb::Error &error)
    {
        std::cerr << error.what() << " (" << error.details() << ")" << std::endl;
        return 1; // error
    }
    catch(const std::exception &error)
    {
        std::cerr << error.what() << std::endl;
        return 1; // error
    }
}
