/*
 * 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_TCRHADISTRIBUTIONMANAGER_H_
#define GEODE_TCRHADISTRIBUTIONMANAGER_H_

#include <geode/internal/geode_base.hpp>

#include "TcrConnectionManager.hpp"
#include "ThinClientDistributionManager.hpp"

namespace apache {
namespace geode {
namespace client {

class ThinClientRegion;
class ThinClientHARegion;
class TcrEndpoint;

/**
 * @brief Distribute data between caches
 */
class APACHE_GEODE_EXPORT TcrHADistributionManager
    : public ThinClientDistributionManager {
 public:
  TcrHADistributionManager(ThinClientRegion* theRegion,
                           TcrConnectionManager& connManager);
  ~TcrHADistributionManager() override = default;
  TcrHADistributionManager(const TcrHADistributionManager&) = delete;
  TcrHADistributionManager& operator=(const TcrHADistributionManager&) = delete;

  void init() override;

  GfErrType registerInterestForRegion(TcrEndpoint* ep,
                                      const TcrMessage* request,
                                      TcrMessageReply* reply) override;

  GfErrType sendSyncRequestRegisterInterestEP(TcrMessage& request,
                                              TcrMessageReply& reply,
                                              bool attemptFailover,
                                              TcrEndpoint* endpoint) override;

  GfErrType sendRequestToEP(const TcrMessage& request, TcrMessageReply& reply,
                            TcrEndpoint* endpoint) override;

  ThinClientRegion* getRegion() { return m_region; }

  void acquireRedundancyLock() override {
    m_connManager.acquireRedundancyLock();
  };

  void releaseRedundancyLock() override {
    m_connManager.releaseRedundancyLock();
  };

 protected:
  GfErrType sendSyncRequestRegisterInterest(
      TcrMessage& request, TcrMessageReply& reply, bool attemptFailover = true,
      ThinClientRegion* region = nullptr,
      TcrEndpoint* endpoint = nullptr) override;

  virtual GfErrType sendSyncRequestCq(TcrMessage& request,
                                      TcrMessageReply& reply);

  void getEndpointNames(
      std::unordered_set<std::string>& endpointNames) override;

  bool preFailoverAction() override;

  bool postFailoverAction(TcrEndpoint* endpoint) override;

 private:
  TcrConnectionManager& m_theTcrConnManager;

  GfErrType sendRequestToPrimary(TcrMessage& request, TcrMessageReply& reply) {
    return m_theTcrConnManager.sendRequestToPrimary(request, reply);
  }

  friend class ThinClientHARegion;
  friend class TcrConnectionManager;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_TCRHADISTRIBUTIONMANAGER_H_
