/*
 * 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_TCRPOOLENDPOINT_H_
#define GEODE_TCRPOOLENDPOINT_H_

#include "TcrEndpoint.hpp"
#include "PoolStatistics.hpp"

namespace apache {
namespace geode {
namespace client {

class ThinClientPoolDM;

class TcrPoolEndPoint : public TcrEndpoint {
 public:
  TcrPoolEndPoint(const std::string& name, CacheImpl* cache,
                  ACE_Semaphore& failoverSema, ACE_Semaphore& cleanupSema,
                  ACE_Semaphore& redundancySema, ThinClientPoolDM* dm);
  ThinClientPoolDM* getPoolHADM() override;

  bool checkDupAndAdd(std::shared_ptr<EventId> eventid) override;
  void processMarker() override;
  std::shared_ptr<QueryService> getQueryService() override;
  void sendRequestForChunkedResponse(const TcrMessage& request,
                                     TcrMessageReply& reply,
                                     TcrConnection* conn) override;
  void closeFailedConnection(TcrConnection*& conn) override;
  GfErrType registerDM(bool clientNotification, bool isSecondary = false,
                       bool isActiveEndpoint = false,
                       ThinClientBaseDM* distMgr = nullptr) override;
  void unregisterDM(bool clientNotification,
                    ThinClientBaseDM* distMgr = nullptr,
                    bool checkQueueHosted = false) override;
  using TcrEndpoint::handleIOException;
  bool handleIOException(const std::string& message, TcrConnection*& conn,
                         bool isBgThread = false) override;
  void handleNotificationStats(int64_t byteLength) override;
  ~TcrPoolEndPoint() override { m_dm = nullptr; }
  bool isMultiUserMode() override;

 protected:
  void closeNotification() override;
  void triggerRedundancyThread() override;

 private:
  ThinClientPoolDM* m_dm;
};

}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_TCRPOOLENDPOINT_H_
