/*
 * 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 "PoolAttributes.hpp"
#include <geode/ExceptionTypes.hpp>
#include <geode/PoolFactory.hpp>

namespace apache {
namespace geode {
namespace client {

PoolAttributes::PoolAttributes()
    : m_isThreadLocalConn(PoolFactory::DEFAULT_THREAD_LOCAL_CONN),
      m_freeConnTimeout(PoolFactory::DEFAULT_FREE_CONNECTION_TIMEOUT),
      m_loadCondInterval(PoolFactory::DEFAULT_LOAD_CONDITIONING_INTERVAL),
      m_sockBufferSize(PoolFactory::DEFAULT_SOCKET_BUFFER_SIZE),
      m_readTimeout(PoolFactory::DEFAULT_READ_TIMEOUT),
      m_minConns(PoolFactory::DEFAULT_MIN_CONNECTIONS),
      m_maxConns(PoolFactory::DEFAULT_MAX_CONNECTIONS),
      m_retryAttempts(PoolFactory::DEFAULT_RETRY_ATTEMPTS),
      m_statsInterval(PoolFactory::DEFAULT_STATISTIC_INTERVAL),
      m_redundancy(PoolFactory::DEFAULT_SUBSCRIPTION_REDUNDANCY),
      m_msgTrackTimeout(
          PoolFactory::DEFAULT_SUBSCRIPTION_MESSAGE_TRACKING_TIMEOUT),
      m_subsAckInterval(PoolFactory::DEFAULT_SUBSCRIPTION_ACK_INTERVAL),
      m_idleTimeout(PoolFactory::DEFAULT_IDLE_TIMEOUT),
      m_pingInterval(PoolFactory::DEFAULT_PING_INTERVAL),
      m_updateLocatorListInterval(
          PoolFactory::DEFAULT_UPDATE_LOCATOR_LIST_INTERVAL),
      m_subsEnabled(PoolFactory::DEFAULT_SUBSCRIPTION_ENABLED),
      m_multiuserSecurityMode(PoolFactory::DEFAULT_MULTIUSER_SECURE_MODE),
      m_isPRSingleHopEnabled(PoolFactory::DEFAULT_PR_SINGLE_HOP_ENABLED),
      m_serverGrp(PoolFactory::DEFAULT_SERVER_GROUP) {}
std::shared_ptr<PoolAttributes> PoolAttributes::clone() {
  return std::make_shared<PoolAttributes>(*this);
}

/** Return true if all the attributes are equal to those of other. */
bool PoolAttributes::operator==(const PoolAttributes& other) const {
  if (m_isThreadLocalConn != other.m_isThreadLocalConn) return false;
  if (m_freeConnTimeout != other.m_freeConnTimeout) return false;
  if (m_loadCondInterval != other.m_loadCondInterval) return false;
  if (m_sockBufferSize != other.m_sockBufferSize) return false;
  if (m_readTimeout != other.m_readTimeout) return false;
  if (m_minConns != other.m_minConns) return false;
  if (m_maxConns != other.m_maxConns) return false;
  if (m_retryAttempts != other.m_retryAttempts) return false;
  if (m_statsInterval != other.m_statsInterval) return false;
  if (m_redundancy != other.m_redundancy) return false;
  if (m_msgTrackTimeout != other.m_msgTrackTimeout) return false;
  if (m_subsAckInterval != other.m_subsAckInterval) return false;
  if (m_idleTimeout != other.m_idleTimeout) return false;
  if (m_pingInterval != other.m_pingInterval) return false;
  if (m_updateLocatorListInterval != other.m_updateLocatorListInterval) {
    return false;
  }
  if (m_subsEnabled != other.m_subsEnabled) return false;
  if (m_multiuserSecurityMode != other.m_multiuserSecurityMode) return false;
  if (m_isPRSingleHopEnabled != other.m_isPRSingleHopEnabled) return false;
  if (m_serverGrp != other.m_serverGrp) return false;

  if (m_initLocList.size() != other.m_initLocList.size()) return false;
  if (m_initServList.size() != other.m_initServList.size()) return false;

  if (!compareVectorOfStrings(m_initLocList, other.m_initLocList)) return false;
  if (!compareVectorOfStrings(m_initServList, other.m_initServList)) {
    return false;
  }

  return true;
}

bool PoolAttributes::compareVectorOfStrings(
    const std::vector<std::string>& thisVector,
    const std::vector<std::string>& otherVector) {
  for (auto&& it : thisVector) {
    bool found = false;
    for (auto&& itOther : otherVector) {
      if (it == itOther) {
        found = true;
        break;
      }
    }

    if (!found) return false;
  }
  return true;
}

void PoolAttributes::addLocator(const std::string& host, int port) {
  if (!m_initServList.empty()) {
    throw IllegalArgumentException(
        "Cannot add both locators and servers to a pool");
  }
  m_initLocList.push_back(host + ":" + std::to_string(port));
}

void PoolAttributes::addServer(const std::string& host, int port) {
  if (!m_initLocList.empty()) {
    throw IllegalArgumentException(
        "Cannot add both locators and servers to a pool");
  }
  m_initServList.push_back(host + ":" + std::to_string(port));
}

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