/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 */

#ifndef SH4LT_SYSV_SHM_H_
#define SH4LT_SYSV_SHM_H_

#include <sys/ipc.h>
#include <sys/shm.h>

#include <string>

#include "../logger/logger.hpp"
#include "../utils/safe-bool-idiom.hpp"
#include "./unix-socket-server.hpp"

namespace sh4lt {

auto force_shm_cleaning(key_t key, logger::Logger* log) -> bool;

class sysVShm : public SafeBoolIdiom {
 public:
  sysVShm(key_t key,
          size_t size,
          logger::Logger* log,
          bool owner = false,
          mode_t unix_permission = UnixSocketServer::kDefaultPermission);
  ~sysVShm() override;
  sysVShm() = delete;
  sysVShm(sysVShm&&) = delete;
  sysVShm(const sysVShm&) = delete;
  auto operator=(const sysVShm&) -> sysVShm& = delete;
  auto operator=(sysVShm&&) -> sysVShm& = default;

  auto get_mem() -> void* { return shm_; }
  [[nodiscard]] auto get_size() const -> std::size_t { return size_; }
  // Maximum size in bytes for a shared memory segment
  static auto get_shmmax(logger::Logger* log) -> unsigned long;
  // System-wide limit on the number of shared memory segments
  static auto get_shmmni(logger::Logger* log) -> unsigned long;

 private:
  logger::Logger* log_;
  key_t key_;
  size_t size_;
  int shmid_;
  bool owner_;            // responsible for creation and deletion of the shm
  void* shm_{(void*)-1};  // man shmat
  [[nodiscard]] auto is_valid() const -> bool final;
};

}  // namespace sh4lt
#endif
