/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#ifndef GEODE_TCPCONN_H_
#define GEODE_TCPCONN_H_

#include <ace/OS.h>
#include <ace/SOCK_Stream.h>
#include <boost/interprocess/mapped_region.hpp>

#include <geode/internal/geode_globals.hpp>

#include "Assert.hpp"
#include "Connector.hpp"
#include "util/Log.hpp"

namespace apache {
namespace geode {
namespace client {

#ifdef WIN32

#define TCPLEVEL IPPROTO_TCP

#else

#include <sys/socket.h>
#include <sys/types.h>

#define TCPLEVEL SOL_TCP

#endif

class APACHE_GEODE_EXPORT TcpConn : public Connector {
 private:
  ACE_SOCK_Stream* m_io;

 protected:
  ACE_INET_Addr m_addr;
  std::chrono::microseconds m_waitMilliSeconds;

  int32_t m_maxBuffSizePool;

  enum SockOp { SOCK_READ, SOCK_WRITE };

  void clearNagle(ACE_HANDLE sock);
  int32_t maxSize(ACE_HANDLE sock, int32_t flag, int32_t size);

  virtual size_t socketOp(SockOp op, char* buff, size_t len,
                          std::chrono::microseconds waitDuration);

  virtual void createSocket(ACE_HANDLE sock);

 public:
  size_t m_chunkSize;

  static size_t getDefaultChunkSize() {
    // Attempt to set chunk size to nearest OS page size
    // for perf improvement
    auto pageSize = boost::interprocess::mapped_region::get_page_size();
    if (pageSize > 16000000) {
      return 16000000;
    } else if (pageSize > 0) {
      return pageSize + (16000000 / pageSize) * pageSize;
    }

    return 16000000;
  }

  TcpConn(const char* hostname, int32_t port,
          std::chrono::microseconds waitSeconds, int32_t maxBuffSizePool);
  TcpConn(const char* ipaddr, std::chrono::microseconds waitSeconds,
          int32_t maxBuffSizePool);

  virtual ~TcpConn() override { close(); }

  // Close this tcp connection
  virtual void close() override;

  void init() override;

  // Listen
  void listen(
      const char* hostname, int32_t port,
      std::chrono::microseconds waitSeconds = DEFAULT_READ_TIMEOUT_SECS);
  void listen(const char* ipaddr, std::chrono::microseconds waitSeconds =
                                      DEFAULT_READ_TIMEOUT_SECS);

  virtual void listen(
      ACE_INET_Addr addr,
      std::chrono::microseconds waitSeconds = DEFAULT_READ_TIMEOUT_SECS);

  // connect
  void connect(const char* hostname, int32_t port,
               std::chrono::microseconds waitSeconds = DEFAULT_CONNECT_TIMEOUT);
  void connect(const char* ipaddr,
               std::chrono::microseconds waitSeconds = DEFAULT_CONNECT_TIMEOUT);

  virtual void connect();

  size_t receive(char* buff, size_t len,
                 std::chrono::microseconds waitSeconds) override;
  size_t send(const char* buff, size_t len,
              std::chrono::microseconds waitSeconds) override;

  virtual void setOption(int32_t level, int32_t option, void* val, size_t len) {
    GF_DEV_ASSERT(m_io != nullptr);

    if (m_io->set_option(level, option, val, static_cast<int32_t>(len)) == -1) {
      int32_t lastError = ACE_OS::last_error();
      LOGERROR("Failed to set option, errno: %d: %s", lastError,
               ACE_OS::strerror(lastError));
    }
  }

  void setIntOption(int32_t level, int32_t option, int32_t val) {
    setOption(level, option, &val, sizeof(int32_t));
  }

  void setBoolOption(int32_t level, int32_t option, bool val) {
    setOption(level, option, &val, sizeof(bool));
  }

  virtual uint16_t getPort() override;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_TCPCONN_H_
