/* Blinker
   Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org>
   Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html
   a blinkenarea.org project */

#ifndef BLINKER_LOCKNAMEFILE_H
#define BLINKER_LOCKNAMEFILE_H

#include "LockMgr.h"
#include "NameFile.h"

namespace Blinker {

/// file containting the name of a lock
class LockNameFile
{
public:
  /**
   * @brief constructor
   * @param[in] file basic file object to treat as lock name file
   * @param[in] lockMgr lock manager
   */
  LockNameFile(const File &file, LockMgr &lockMgr);

  /// destructor
  ~LockNameFile();

private:
  /// copy constructor disabled
  LockNameFile(const LockNameFile &);

  /// assignment operator disabled
  const LockNameFile & operator=(const LockNameFile &);

public:
  /// update lock name if file has been modified
  void updateIfModified();

  /**
   * @brief check if lock is free,
   *        i.e., no lock configured (i.e. no lock file),
   *        lock not locked or taken by this object
   * @return whether lock is free
   */
  bool isfree() const;

  /**
   * @brief take the lock,
   *        success if no lock configured (i.e. no lock file),
   *        lock was not locked and could be taken by this object
   *        or lock was already taken by this object
   * @return whether lock could be taken
   */
  bool take();

  /// release taken lock
  void release();

protected:
  /// update pointer to referenced lock based on name file contents
  void update();

public:
  NameFile m_nameFile; ///< file containing lock name
  LockMgr &m_lockMgr; ///< reference to lock manager
  class Lock *m_refLock; ///< pointer to re referenced lock (if any) or nullptr
  class Lock *m_takenLock; ///< pointer to taken lock (if any) or nullptr
}; // class LockNameFile

} // namespace Blinker

#endif // #ifndef BLINKER_LOCKNAMEFILE_H

