/*
 * 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_UNIX_SOCKET_CLIENT_H_
#define SH4LT_UNIX_SOCKET_CLIENT_H_

#include <atomic>
#include <string>

#include "../logger/logger.hpp"
#include "../utils/safe-bool-idiom.hpp"
#include "../utils/threaded-wrapper.hpp"
#include "./unix-socket-protocol.hpp"
#include "./unix-socket.hpp"

namespace sh4lt {

class UnixSocketClient : public SafeBoolIdiom {
 public:
  UnixSocketClient(const std::string& path, logger::Logger* log);
  ~UnixSocketClient() override;
  UnixSocketClient() = delete;
  UnixSocketClient(UnixSocketClient&&) = delete;
  UnixSocketClient(const UnixSocketClient&) = delete;
  auto operator=(const UnixSocketClient&) -> UnixSocketClient& = delete;
  auto operator=(UnixSocketClient&&) -> UnixSocketClient& = delete;

  auto start(UnixSocketProtocol::ClientSide* proto) -> bool;

 private:
  static const int kServerTimeoutMicrosec{10000};
  std::string path_;
  UnixSocket socket_;
  logger::Logger* log_;
  std::atomic_short quit_{0};
  // connection
  std::mutex connected_mutex_{};
  std::condition_variable cv_{};
  bool connected_{false};
  bool is_valid_{false};
  UnixSocketProtocol::ClientSide* proto_{nullptr};
  std::unique_ptr<ThreadedWrapper<>> done_{};
  [[nodiscard]] auto is_valid() const -> bool final;
  void server_interaction();
};

}  // namespace sh4lt
#endif
