{*
 *******************************************************************************
 *
 *  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    riegl.rdb.pointcloud.changelog.pas
 * \author  RIEGL LMS GmbH, Austria
 * \brief   Manage point cloud changelog
 * \version 2020-07-03/AW: Initial version
 *
 * Each database maintains a log of changes made to a point cloud.
 *
 * A separate log entry is created for each database transaction or management
 * operation. A log entry contains log messages with high-level information
 * about the modifications as follows:
 *
 *   - current transaction number, title, agent, date and time
 *   - number of data points added, updated, removed
 *   - list of point attributes affected by point operations
 *   - list of point attributes added, updated, removed
 *   - list of metadata entries added, updated, removed
 *   - modification of level-of-detail parameters
 *   - management: restore transaction, finalize and vacuum database
 *   - optional: log messages (some text) provided by client software
 *
 * Details like actual point data, attribute definitions or metadata values are
 * not recorded.
 *
 * \see riegl::rdb::Pointcloud::changelog()
 *
 * \since 2.3.0
 *
 *******************************************************************************
 *}

unit riegl.rdb.pointcloud.changelog;

{******************************************************************************}
{***} INTERFACE {**************************************************************}
{******************************************************************************}

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

uses
  riegl.rdb,
  riegl.rdb.context;

//---< RDB LIBRARY IMPORTS >----------------------------------------------------

//______________________________________________________________________________
{*!
 * \brief Append text to current log entry
 *
 * This function appends text message(s) to the log entry of the current
 * database transaction. As with all strings in RDB, the characters are
 * expected to be UTF-8 encoded. Line endings are normalized (i.e. CR+LF
 * and CR are converted to LF).
 *
 * Calling this function while no transaction is active has no effect.
 *
 * \since 2.3.0
 *}
function rdb_pointcloud_changelog_append_log_message(
  Context    : TRDBContextHandle;    //!< [in] library context
  Pointcloud : TRDBPointcloudHandle; //!< [in] point cloud handle
  Message    : TRDBString            //!< [in] log message to append
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Verify log entry signature
 *
 * Returns 'false' (0) if:
 *
 * - there is no signature for the log entry
 * - the signature does not match the log messages
 * - a wrong signature encryption key was given
 *
 * Otherwise returns 'true' (1).
 *
 * \since 2.3.0
 *}
function rdb_pointcloud_changelog_verify_log_entry_cf(
  Entry     : TRDBString; //!< [in] log entry messages to verify
  Method    : TRDBUInt32; //!< [in] signature method (1: default)
  KeySize   : TRDBUInt32; //!< [in] signature encryption key size (at least 32 byte)
  KeyData   : Pointer;    //!< [in] signature encryption key buffer
  var Valid : TRDBUInt32  //!< [out] 0 if the signature is not valid
) : TRDBResultCF; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Export changelog to text file
 *
 * This function exports the entire changelog to a single text file.
 * The file is UTF-8 encoded and text lines are separated by a single
 * line feed character (LF, ASCII 0x0A), regardless of the operating
 * system the file was created on.
 *
 * \since 2.3.0
 *}
function rdb_pointcloud_changelog_export_to_textfile(
  Context    : TRDBContextHandle;    //!< [in] library context
  Pointcloud : TRDBPointcloudHandle; //!< [in] point cloud handle
  Filename   : TRDBString            //!< [in] output text filename
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//______________________________________________________________________________
{*!
 * \brief Import changelog from database
 *
 * This function imports the entire changelog from an other database.
 * This is intended for applications where a database is to be replaced
 * by a new one (often derived from the old one) and the processing
 * history is to be retained.
 *
 * \since 2.3.0
 *}
function rdb_pointcloud_changelog_import_from_database(
  Context    : TRDBContextHandle;    //!< [in] library context
  Pointcloud : TRDBPointcloudHandle; //!< [in] point cloud handle
  Filename   : TRDBString            //!< [in] input database filename
) : TRDBResult; cdecl; external riegl.rdb.RDB_LIBRARY_FILENAME;

//---< CLASS TRDBPointcloudChangelog >------------------------------------------
{*!
 * \brief Manage point cloud changelog
 *
 * Each database maintains a log of changes made to a point cloud.
 *
 * A separate log entry is created for each database transaction or management
 * operation. A log entry contains log messages with high-level information
 * about the modifications as follows:
 *
 *   - current transaction number, title, agent, date and time
 *   - number of data points added, updated, removed
 *   - list of point attributes affected by point operations
 *   - list of point attributes added, updated, removed
 *   - list of metadata entries added, updated, removed
 *   - modification of level-of-detail parameters
 *   - management: restore transaction, finalize and vacuum database
 *   - optional: log messages (some text) provided by client software
 *
 * Details like actual point data, attribute definitions or metadata values are
 * not recorded.
 *
 * \see riegl::rdb::Pointcloud::changelog()
 *
 * \since 2.3.0
 *}
type
  TRDBPointcloudChangelog = class(System.TObject)
  public
    {*!
     * \brief Constructor
     * \note  You cannot create new TRDBPointcloudChangelog objects directly,
     *        use riegl::rdb::Pointcloud::changelog() instead.
     *}
    constructor Create(Parent : System.TObject); reintroduce;
    destructor  Destroy; override;

    {*!
     * \brief Append text to current log entry
     *
     * This function appends text message(s) to the log entry of the current
     * database transaction. As with all strings in RDB, the characters are
     * expected to be UTF-8 encoded. Line endings are normalized (i.e. CR+LF
     * and CR are converted to LF).
     *
     * Calling this function while no transaction is active has no effect.
     *
     * \since 2.3.0
     *}
    procedure AppendMessage(const Message : System.String);

    {*!
     * \brief Verify log entry signature
     *
     * Returns 'false' if:
     *
     * - there is no signature for the log entry
     * - the signature does not match the log messages
     * - a wrong signature encryption key was given
     *
     * Otherwise returns 'true'.
     *
     * \since 2.3.0
     *}
    class function VerifyLogEntry(
      const Entry   : System.String; //!< [in] log entry messages to verify
      const Method  : TRDBUInt32;    //!< [in] signature method (1: default)
      const KeySize : TRDBUInt32;    //!< [in] signature encryption key size (at least 32 byte)
      const KeyData : Pointer        //!< [in] signature encryption key buffer
    ) : Boolean;

    {*!
     * \brief Export changelog to text file
     *
     * This function exports the entire changelog to a single text file.
     * The file is UTF-8 encoded and text lines are separated by a single
     * line feed character (LF, ASCII 0x0A), regardless of the operating
     * system the file was created on.
     *
     * \since 2.3.0
     *}
    procedure ExportToTextfile(
      const Filename : System.String //!< [in] output text filename
    );

    {*!
     * \brief Import changelog from database
     *
     * This function imports the entire changelog from an other database.
     * This is intended for applications where a database is to be replaced
     * by a new one (often derived from the old one) and the processing
     * history is to be retained.
     *
     * \since 2.3.0
     *}
    procedure ImportFromDatabase(
      const Filename : System.String //!< [in] input database filename
    );

  private
    FContext    : TRDBContext;
    FPointcloud : TRDBPointcloudHandle;
  end;

{******************************************************************************}
{***} IMPLEMENTATION {*********************************************************}
{******************************************************************************}

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

uses
  riegl.rdb.pointcloud;

//---< TRDBPointcloudChangelog::PUBLIC >----------------------------------------

constructor TRDBPointcloudChangelog.Create(Parent : System.TObject);
begin
  inherited Create;
  FContext    := (Parent as TRDBPointcloud).Context;
  FPointcloud := (Parent as TRDBPointcloud).Pointcloud;
end;

destructor TRDBPointcloudChangelog.Destroy;
begin
  inherited;
end;

procedure TRDBPointcloudChangelog.AppendMessage(const Message : System.String);
begin
  FContext.Check(rdb_pointcloud_changelog_append_log_message(
    FContext.Handle, FPointcloud, TRDBString(AnsiToUtf8(Message))
  ));
end;

class function TRDBPointcloudChangelog.VerifyLogEntry(
  const Entry   : System.String;
  const Method  : TRDBUInt32;
  const KeySize : TRDBUInt32;
  const KeyData : Pointer
) : Boolean;
var
  Valid : TRDBUInt32;
begin
  TRDBContext.Check(rdb_pointcloud_changelog_verify_log_entry_cf(
    TRDBString(AnsiToUtf8(Entry)),
    Method, KeySize, KeyData,
    Valid
  ));
  Result := (Valid <> 0);
end;

procedure TRDBPointcloudChangelog.ExportToTextfile(const Filename : System.String);
begin
  FContext.Check(rdb_pointcloud_changelog_export_to_textfile(
    FContext.Handle, FPointcloud, TRDBString(AnsiToUtf8(Filename))
  ));
end;

procedure TRDBPointcloudChangelog.ImportFromDatabase(const Filename : System.String);
begin
  FContext.Check(rdb_pointcloud_changelog_import_from_database(
    FContext.Handle, FPointcloud, TRDBString(AnsiToUtf8(Filename))
  ));
end;

end.

