#pragma once

#ifndef GEODE_TCRHADISTRIBUTIONMANAGER_H_
#define GEODE_TCRHADISTRIBUTIONMANAGER_H_

/*
 * 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.
 */

#include <geode/CacheAttributes.hpp>
#include <geode/internal/geode_base.hpp>

#include "TcrEndpoint.hpp"
#include "ThinClientDistributionManager.hpp"

namespace apache {
namespace geode {
namespace client {

class ThinClientRegion;
class ThinClientHARegion;
/**
 * @brief Distribute data between caches
 */
class APACHE_GEODE_EXPORT TcrHADistributionManager
    : public ThinClientDistributionManager {
 public:
  TcrHADistributionManager(ThinClientRegion* theRegion,
                           TcrConnectionManager& connManager,
                           std::shared_ptr<CacheAttributes> cacheAttributes);
  ~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:
  std::shared_ptr<CacheAttributes> m_cacheAttributes;
  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_
