// Durability modes: sync flags, sync_period/sync_bytes
// Textbook section: Volume II, chapter 10, "Durability modes",
//   sections "Sync flags", "syncbytes/syncperiod".
// What it demonstrates: opening the same database with different durability
//   modes (robust_synchronous / half_synchronous / lazy); an explicit flush
//   to disk via sync_to_disk(); setting sync_bytes/sync_period.
// Build: g++ -std=c++17 -I<libmdbx-include> -I../common 13-sync-modes.c++ -lmdbx
// Run: ./13-sync-modes
// Expected output:
//   durable: ok
//   nometasync: ok
//   safe_nosync: ok
//   ok: sync modes switched between opens; sync_to_disk works
// On failure — message to stderr and exit 1.
//
// SPDX-License-Identifier: Apache-2.0

#include <iostream>
#include <string>

#include "common.h++"
#include <mdbx.h++>

int main() {
  try {
    const std::string path = std::string(example::tmpdir()) + "/mdbx-13-sync-modes.mdbx";
    mdbx::env::remove(path);

    // Run 1: full durability (sync before the commit returns).
    {
      auto env = example::env_open(path, mdbx::env::operate_parameters().robust_synchronous());
      auto txn = env.start_write();
      auto table = txn.open_map(nullptr);
      txn.insert(table, mdbx::slice("key"), mdbx::slice("v1"));
      txn.commit();
      // an explicit flush to disk
      env.sync_to_disk(true);
      std::cout << "durable: ok\n";
    }

    // Run 2: NOMETASYNC (metadata is not synced on every commit).
    {
      auto env = example::env_open(path, mdbx::env::operate_parameters().half_synchronous_weak_last());
      auto txn = env.start_read();
      auto table = txn.open_map(nullptr);
      std::cout << "nometasync: " << txn.get(table, mdbx::slice("key")).as_string() << "\n";
      txn.abort();
    }

    // Run 3: SAFE_NOSYNC (data is on disk, metadata may lag behind).
    {
      auto env = example::env_open(path, mdbx::env::operate_parameters().lazy_weak_tail());
      // sync_bytes = 64 KiB
      env.set_sync_threshold(64 * 1024);
      // sync_period = 1 s
      env.set_sync_period__seconds_double(1.0);
      auto txn = env.start_read();
      auto table = txn.open_map(nullptr);
      std::cout << "safe_nosync: " << txn.get(table, mdbx::slice("key")).as_string() << "\n";
      txn.abort();
    }

    std::cout << "ok: sync modes switched between opens; sync_to_disk works\n";
    return EXIT_SUCCESS;
  } catch (const std::exception &ex) {
    std::cerr << "error: " << ex.what() << "\n";
    return EXIT_FAILURE;
  }
}