// Durability modes: sync flags, sync_period/sync_bytes
// Раздел учебника: Том II, глава 10, «Режимы долговечности»,
//   разделы «Флаги синхронизации», «syncbytes/syncperiod».
// Что демонстрирует: открытие одной и той же БД с разными режимами
//   долговечности (robust_synchronous / half_synchronous / lazy); явный сброс
//   на диск через sync_to_disk(); установку sync_bytes/sync_period.
// Сборка: g++ -std=c++17 -I<libmdbx-include> -I../common 13-sync-modes.c++ -lmdbx
// Запуск: ./13-sync-modes
// Ожидаемый вывод:
//   durable: ok
//   nometasync: ok
//   safe_nosync: ok
//   ok: sync modes switched between opens; sync_to_disk works
// При сбое — сообщение в stderr и 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);

    // Прогон 1: полная долговечность (sync перед ответом коммита).
    {
      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();
      // явный сброс на диск
      env.sync_to_disk(true);
      std::cout << "durable: ok\n";
    }

    // Прогон 2: NOMETASYNC (метаданные не синхронизируются при каждом коммите).
    {
      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();
    }

    // Прогон 3: SAFE_NOSYNC (данные на диске, метаданные могут отставать).
    {
      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;
  }
}