/*
 * 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_THINCLIENTDISTRIBUTIONMANAGER_H_
#define GEODE_THINCLIENTDISTRIBUTIONMANAGER_H_

#include <mutex>

#include "ThinClientBaseDM.hpp"

namespace apache {
namespace geode {
namespace client {

class ThinClientDistributionManager : public ThinClientBaseDM {
 public:
  ThinClientDistributionManager(TcrConnectionManager& connManager,
                                ThinClientRegion* region);
  ~ThinClientDistributionManager() override = default;

  void init() override;
  void destroy(bool keepalive = false) override;

  virtual GfErrType sendSyncRequest(TcrMessage& request, TcrMessageReply& reply,
                                    bool attemptFailover = true,
                                    bool isBGThread = false) override;

  void failover() override;

  void acquireFailoverLock() override { m_endpointsLock.lock(); }
  void releaseFailoverLock() override { m_endpointsLock.unlock(); }

  TcrEndpoint* getActiveEndpoint() override {
    return m_endpoints[m_activeEndpoint];
  }
  bool isEndpointAttached(TcrEndpoint* ep) override;

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

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

  GfErrType selectEndpoint(std::vector<int>& randIndex, bool& doRand,
                           bool useActiveEndpoint = false,
                           bool forceSelect = false);

  GfErrType connectToEndpoint(int epIndex);

  virtual void postUnregisterAction();

  virtual bool preFailoverAction();

  virtual bool postFailoverAction(TcrEndpoint* endpoint);

  virtual void destroyAction();

  std::shared_ptr<Properties> getCredentials(TcrEndpoint* ep);

  GfErrType sendUserCredentials(std::shared_ptr<Properties> credentials,
                                TcrEndpoint* ep);

  volatile int m_activeEndpoint;

  std::vector<TcrEndpoint*> m_endpoints;
  std::recursive_mutex m_endpointsLock;
};
}  // namespace client
}  // namespace geode
}  // namespace apache

#endif  // GEODE_THINCLIENTDISTRIBUTIONMANAGER_H_
