/*
 * 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 "CacheXmlParser.hpp"

#include <chrono>

#include <geode/PoolFactory.hpp>
#include <geode/PoolManager.hpp>
#include <geode/internal/chrono/duration.hpp>

#include "AutoDelete.hpp"
#include "CacheImpl.hpp"
#include "CacheRegionHelper.hpp"
#include "util/string.hpp"

#if defined(_WIN32)
#include <windows.h>
#else
#include <dlfcn.h>
#endif

namespace apache {
namespace geode {
namespace client {

namespace impl {
void* getFactoryFunc(const std::string& lib, const std::string& funcName);
}  // namespace impl

namespace {

using apache::geode::client::impl::getFactoryFunc;

std::vector<std::pair<std::string, int>> parseEndPoints(
    const std::string& str) {
  std::vector<std::pair<std::string, int>> endPoints;
  std::string::size_type start = 0;
  std::string::size_type pos = str.find_first_of(',');
  while (std::string::npos != pos) {
    const std::string endPoint(str.substr(start, pos - start));
    const std::string::size_type split = endPoint.find_last_of(':');
    if (std::string::npos == split) {
      endPoints.push_back(std::pair<std::string, int>(endPoint, 0));
    } else {
      int port = 0;
      try {
        port = std::stoi(endPoint.substr(split + 1));
      } catch (...) {
        // NOP
      }
      endPoints.push_back(
          std::pair<std::string, int>(endPoint.substr(0, split), port));
    }
    start = pos + 1;
    pos = str.find_first_of(',', start);
  }
  return endPoints;
}
}  // namespace

/////////////////XML Parser Callback functions////////////////////////

extern "C" void startElementSAX2Function(void* ctx, const xmlChar* name,
                                         const xmlChar** atts) {
  CacheXmlParser* parser = (CacheXmlParser*)ctx;
  if (!parser) {
    Log::error("CacheXmlParser::startElementSAX2Function:Parser is nullptr");
    return;
  }

  if ((!parser->isCacheXmlException()) &&
      (!parser->isIllegalStateException()) &&
      (!parser->isAnyOtherException())) {
    try {
      auto uname =
          reinterpret_cast<const char*>(const_cast<unsigned char*>(name));
      if (std::strcmp(uname, parser->CACHE) == 0) {
        parser->startCache(ctx, atts);
      } else if (strcmp(uname, parser->CLIENT_CACHE) == 0) {
        parser->startCache(ctx, atts);
      } else if (strcmp(uname, parser->PDX) == 0) {
        parser->startPdx(atts);
      } else if (strcmp(uname, parser->REGION) == 0) {
        parser->incNesting();
        parser->startRegion(atts, parser->isRootLevel());
      } else if (strcmp(uname, parser->ROOT_REGION) == 0) {
        parser->incNesting();
        parser->startRegion(atts, parser->isRootLevel());
      } else if (strcmp(uname, parser->REGION_ATTRIBUTES) == 0) {
        parser->startRegionAttributes(atts);
      } else if (strcmp(uname, parser->REGION_TIME_TO_LIVE) == 0) {
      } else if (strcmp(uname, parser->REGION_IDLE_TIME) == 0) {
      } else if (strcmp(uname, parser->ENTRY_TIME_TO_LIVE) == 0) {
      } else if (strcmp(uname, parser->ENTRY_IDLE_TIME) == 0) {
      } else if (strcmp(uname, parser->EXPIRATION_ATTRIBUTES) == 0) {
        parser->startExpirationAttributes(atts);
      } else if (strcmp(uname, parser->CACHE_LOADER) == 0) {
        parser->startCacheLoader(atts);
      } else if (strcmp(uname, parser->CACHE_WRITER) == 0) {
        parser->startCacheWriter(atts);
      } else if (strcmp(uname, parser->CACHE_LISTENER) == 0) {
        parser->startCacheListener(atts);
      } else if (strcmp(uname, parser->PARTITION_RESOLVER) == 0) {
        parser->startPartitionResolver(atts);
      } else if (strcmp(uname, parser->PERSISTENCE_MANAGER) == 0) {
        parser->startPersistenceManager(atts);
      } else if (strcmp(uname, parser->PROPERTIES) == 0) {
      } else if (strcmp(uname, parser->PROPERTY) == 0) {
        parser->startPersistenceProperties(atts);
      } else if (strcmp(uname, parser->POOL) == 0) {
        parser->startPool(atts);
      } else if (strcmp(uname, parser->LOCATOR) == 0) {
        parser->startLocator(atts);
      } else if (strcmp(uname, parser->SERVER) == 0) {
        parser->startServer(atts);
      } else {
        throw CacheXmlException("XML:Unknown XML element \"" +
                                std::string(uname) + "\"");
      }
    } catch (const CacheXmlException& e) {
      parser->setCacheXmlException();
      std::string s = e.what();
      parser->setError(s);
    } catch (const IllegalStateException& ex) {
      parser->setIllegalStateException();
      std::string s = ex.what();
      parser->setError(s);
    } catch (const Exception& ex) {
      parser->setAnyOtherException();
      std::string s = ex.what();
      parser->setError(s);
    }
  }  // flag
}

extern "C" void endElementSAX2Function(void* ctx, const xmlChar* name) {
  CacheXmlParser* parser = (CacheXmlParser*)ctx;
  if (!parser) {
    Log::error(
        "Error occured while xml parsing: "
        "CacheXmlParser:startElementSAX2Function:Parser is nullptr");
    return;
  }

  if ((!parser->isCacheXmlException()) &&
      (!parser->isIllegalStateException()) &&
      (!parser->isAnyOtherException())) {
    try {
      auto uname =
          reinterpret_cast<const char*>(const_cast<unsigned char*>(name));
      if (strcmp(uname, parser->CACHE) == 0) {
        parser->endCache();
      } else if (strcmp(uname, parser->CLIENT_CACHE) == 0) {
        parser->endCache();
      } else if (strcmp(uname, parser->PDX) == 0) {
        parser->endPdx();
      } else if (strcmp(uname, parser->REGION) == 0) {
        parser->endRegion(parser->isRootLevel());
        parser->decNesting();
      } else if (strcmp(uname, parser->ROOT_REGION) == 0) {
        parser->endRegion(parser->isRootLevel());
        parser->decNesting();
      } else if (strcmp(uname, parser->REGION_ATTRIBUTES) == 0) {
        parser->endRegionAttributes();
      } else if (strcmp(uname, parser->REGION_TIME_TO_LIVE) == 0) {
        parser->endRegionTimeToLive();
      } else if (strcmp(uname, parser->REGION_IDLE_TIME) == 0) {
        parser->endRegionIdleTime();
      } else if (strcmp(uname, parser->ENTRY_TIME_TO_LIVE) == 0) {
        parser->endEntryTimeToLive();
      } else if (strcmp(uname, parser->ENTRY_IDLE_TIME) == 0) {
        parser->endEntryIdleTime();
      } else if (strcmp(uname, parser->EXPIRATION_ATTRIBUTES) == 0) {
      } else if (strcmp(uname, parser->CACHE_LOADER) == 0) {
      } else if (strcmp(uname, parser->CACHE_WRITER) == 0) {
      } else if (strcmp(uname, parser->CACHE_LISTENER) == 0) {
      } else if (strcmp(uname, parser->PARTITION_RESOLVER) == 0) {
      } else if (strcmp(uname, parser->PERSISTENCE_MANAGER) == 0) {
        parser->endPersistenceManager();
      } else if (strcmp(uname, parser->PROPERTIES) == 0) {
      } else if (strcmp(uname, parser->PROPERTY) == 0) {
      } else if (strcmp(uname, parser->POOL) == 0) {
        parser->endPool();
      } else if (strcmp(uname, parser->LOCATOR) == 0) {
        // parser->endLocator();
      } else if (strcmp(uname, parser->SERVER) == 0) {
        // parser->endServer();
      } else {
        throw CacheXmlException("XML:Unknown XML element \"" +
                                std::string(uname) + "\"");
      }
    } catch (CacheXmlException& e) {
      parser->setCacheXmlException();
      std::string s = e.what();
      parser->setError(s);
    } catch (IllegalStateException& ex) {
      parser->setIllegalStateException();
      std::string s = ex.what();
      parser->setError(s);
    } catch (Exception& ex) {
      parser->setAnyOtherException();
      std::string s = ex.what();
      parser->setError(s);
    }
  }  // flag
}

/**
 * warningDebug:
 * @ctxt:  An XML parser context
 * @msg:  the message to display/transmit
 * @...:  extra parameters for the message display
 *
 * Display and format a warning messages, gives file, line, position and
 * extra parameters.
 */
extern "C" void warningDebug(void*, const char* msg, ...) {
  char logmsg[2048];
  va_list args;
  va_start(args, msg);
  vsprintf(logmsg, msg, args);
  va_end(args);
  LOGWARN("SAX.warning during XML declarative client initialization: %s",
          logmsg);
}

/**
 * fatalErrorDebug:
 * @ctxt:  An XML parser context
 * @msg:  the message to display/transmit
 * @...:  extra parameters for the message display
 *
 * Display and format a fatalError messages, gives file, line, position and
 * extra parameters.
 */
extern "C" void fatalErrorDebug(void* ctx, const char* msg, ...) {
  char buf[1024];
  va_list args;

  va_start(args, msg);
  CacheXmlParser* parser = (CacheXmlParser*)ctx;
  vsprintf(buf, msg, args);
  std::string stringMsg(buf);
  parser->setParserMessage(parser->getParserMessage() + stringMsg);
  va_end(args);
}

/////////////End of XML Parser Cackllback functions///////////////

///////////////static variables of the class////////////////////////

LibraryCacheLoaderFn CacheXmlParser::managedCacheLoaderFn = nullptr;
LibraryCacheListenerFn CacheXmlParser::managedCacheListenerFn = nullptr;
LibraryPartitionResolverFn CacheXmlParser::managedPartitionResolverFn = nullptr;
LibraryCacheWriterFn CacheXmlParser::managedCacheWriterFn = nullptr;
LibraryPersistenceManagerFn CacheXmlParser::managedPersistenceManagerFn =
    nullptr;

//////////////////////////////////////////////////////////////////

CacheXmlParser::CacheXmlParser(Cache* cache)
    : m_cacheCreation(nullptr),
      m_nestedRegions(0),
      m_config(nullptr),
      m_parserMessage(""),
      m_flagCacheXmlException(false),
      m_flagIllegalStateException(false),
      m_flagAnyOtherException(false),
      m_flagExpirationAttribute(false),
      m_poolFactory(nullptr),
      m_cache(cache) {
  static xmlSAXHandler saxHandler = {
      nullptr,                  /* internalSubset */
      nullptr,                  /* isStandalone */
      nullptr,                  /* hasInternalSubset */
      nullptr,                  /* hasExternalSubset */
      nullptr,                  /* resolveEntity */
      nullptr,                  /* getEntity */
      nullptr,                  /* entityDecl */
      nullptr,                  /* notationDecl */
      nullptr,                  /* attributeDecl */
      nullptr,                  /* elementDecl */
      nullptr,                  /* unparsedEntityDecl */
      nullptr,                  /* setDocumentLocator */
      nullptr,                  /* startDocument */
      nullptr,                  /* endDocument */
      startElementSAX2Function, /* startElement */
      endElementSAX2Function,   /* endElement */
      nullptr,                  /* reference */
      nullptr,                  /* characters */
      nullptr,                  /* ignorableWhitespace */
      nullptr,                  /* processingInstruction */
      nullptr,                  // commentDebug, /* comment */
      warningDebug,             /* xmlParserWarning */
      fatalErrorDebug,          /* xmlParserError */
      nullptr,                  /* xmlParserError */
      nullptr,                  /* getParameterEntity */
      nullptr,                  /* cdataBlock; */
      nullptr,                  /* externalSubset; */
      XML_SAX2_MAGIC,
      nullptr,
      nullptr, /* startElementNs */
      nullptr, /* endElementNs */
      nullptr  /* xmlStructuredErrorFunc */
  };

  m_saxHandler = saxHandler;

  namedRegions = CacheImpl::getRegionShortcut();
}

void CacheXmlParser::parseFile(const char* filename) {
  int res = 0;

  res = xmlSAXUserParseFile(&this->m_saxHandler, this, filename);

  if (res == -1) {
    throw CacheXmlException("Xml file " + std::string(filename) + " not found");
  }
  handleParserErrors(res);
}

void CacheXmlParser::parseMemory(const char* buffer, int size) {
  int res = 0;
  res = xmlSAXUserParseMemory(&this->m_saxHandler, this, buffer, size);

  if (res == -1) {
    throw CacheXmlException("Unable to read buffer.");
  }
  handleParserErrors(res);
}

void CacheXmlParser::handleParserErrors(int res) {
  if (res != 0)  // xml file is not well-formed
  {
    Log::error("Error code returned by xml parser is : " + std::to_string(res));
    throw CacheXmlException("Xml file is not well formed. Error _stack: \n" +
                            std::string(this->m_parserMessage));
  }
  std::string temp = this->getError();
  if (temp.empty()) {
    Log::info("Xml file parsed successfully");
  } else {
    // well formed, but not according to our specs(dtd errors thrown manually)
    if (this->m_flagCacheXmlException) {
      throw CacheXmlException(temp);
    } else if (this->m_flagIllegalStateException) {
      throw IllegalStateException(temp);
    } else if (this->m_flagAnyOtherException) {
      throw UnknownException(temp);
    }
    this->setError("");
  }
}

//////////////////////  Static Methods  //////////////////////

/**
 * Parses XML data and from it creates an instance of
 * <code>CacheXmlParser</code> that can be used to create
 * the {@link Cache}, etc.
 *
 * @param  cacheXml
 *         The xml file
 *
 * @throws CacheXmlException
 *         Something went wrong while parsing the XML
 * @throws OutOfMemoryException
 * @throws CacheXmlException
 *         If xml file is not well-formed or
 *         Something went wrong while parsing the XML
 * @throws IllegalStateException
 *         If xml file is well-flrmed but not valid
 * @throws UnknownException otherwise
 */
CacheXmlParser* CacheXmlParser::parse(const char* cacheXml, Cache* cache) {
  CacheXmlParser* handler;
  _GEODE_NEW(handler, CacheXmlParser(cache));
  // use RAII to delete the handler object in case of exceptions
  DeleteObject<CacheXmlParser> delHandler(handler);

  {
    handler->parseFile(cacheXml);
    delHandler.noDelete();
    return handler;
  }
}

void CacheXmlParser::setAttributes(Cache*) {}

/**
 * Creates cache artifacts ({@link Cache}s, etc.) based upon the XML
 * parsed by this parser.
 *
 * @param  cache
 *         The cachewhcih is to be populated
 * @throws OutOfMemoryException if the memory allocation failed
 * @throws NotConnectedException if the cache is not connected
 * @throws InvalidArgumentException if the attributePtr is nullptr.
 * or if RegionAttributes is null or if regionName is null,
 * the empty   string, or contains a '/'
 * @throws RegionExistsException
 * @throws CacheClosedException if the cache is closed
 *         at the time of region creation
 * @throws UnknownException otherwise
 *
 */
void CacheXmlParser::create(Cache* cache) {
  // use DeleteObject class to delete m_cacheCreation in case of exceptions
  DeleteObject<CacheXmlCreation> delCacheCreation(m_cacheCreation);

  if (cache == nullptr) {
    throw IllegalArgumentException(
        "XML:No cache specified for performing configuration");
  }
  if (!m_cacheCreation) {
    throw CacheXmlException("XML: Element <cache> was not provided in the xml");
  }
  m_cacheCreation->create(cache);
  delCacheCreation.noDelete();
  Log::info("Declarative configuration of cache completed successfully");
}

void CacheXmlParser::startCache(void*, const xmlChar** atts) {
  if (atts) {
    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
      if (value.empty()) {
        throw CacheXmlException("XML: No value provided for attribute: " +
                                name);
      }

      if (ENDPOINTS == name) {
        if (m_poolFactory) {
          for (auto&& endPoint : parseEndPoints(value)) {
            m_poolFactory->addServer(endPoint.first, endPoint.second);
          }
        }
      } else if (REDUNDANCY_LEVEL == name) {
        m_poolFactory->setSubscriptionRedundancy(std::stoi(value));
      }
    }
  }
  _GEODE_NEW(m_cacheCreation, CacheXmlCreation());
}

void CacheXmlParser::startPdx(const xmlChar** atts) {
  if (!atts) {
    return;
  }

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (value.empty()) {
      throw CacheXmlException("XML: No value provided for attribute: " + name);
    }

    if (IGNORE_UNREAD_FIELDS == name) {
      bool flag = false;
      std::transform(value.begin(), value.end(), value.begin(), ::tolower);
      if ("false" == value) {
        flag = false;
      } else if ("true" == value) {
        flag = true;
      } else {
        throw CacheXmlException(
            "XML: " + value +
            " is not a valid value for the attribute <ignore-unread-fields>");
      }
      m_cacheCreation->setPdxIgnoreUnreadField(flag);
    } else if (READ_SERIALIZED == name) {
      bool flag = false;
      std::transform(value.begin(), value.end(), value.begin(), ::tolower);
      if ("false" == value) {
        flag = false;
      } else if ("true" == value) {
        flag = true;
      } else {
        throw CacheXmlException(
            "XML: " + value +
            " is not a valid value for the attribute <ignore-unread-fields>");
      }
      m_cacheCreation->setPdxReadSerialized(flag);
    } else {
      throw CacheXmlException("XML:Unrecognized pdx attribute " + name);
    }
  }
}

void CacheXmlParser::endPdx() {}

void CacheXmlParser::startLocator(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <locator>. A locator requires a host "
        "and port");
  }
  m_poolFactory = std::static_pointer_cast<PoolFactory>(_stack.top());

  std::string host;
  std::string port;
  int attrsCount = 0;

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (value.empty()) {
      throw CacheXmlException("XML: No value provided for attribute: " + name);
    }

    if (HOST == name) {
      host = std::move(value);
    } else if (PORT == name) {
      port = std::move(value);
    } else {
      throw CacheXmlException("XML:Unrecognized locator attribute");
    }

    ++attrsCount;
  }

  if (attrsCount < 2) {
    throw CacheXmlException(
        "XML:Not enough attributes provided for a <locator> - host and port "
        "required");
  }

  m_poolFactory->addLocator(host, std::stoi(port));
}

void CacheXmlParser::startServer(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <server>. A server requires a host and "
        "port");
  }
  auto factory = std::static_pointer_cast<PoolFactory>(_stack.top());

  std::string host;
  std::string port;
  int attrsCount = 0;

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (value.empty()) {
      throw CacheXmlException("XML: No value provided for attribute: " + name);
    }

    if (HOST == name) {
      host = std::move(value);
    } else if (PORT == name) {
      port = std::move(value);
    } else {
      throw CacheXmlException("XML:Unrecognized server attribute");
    }

    ++attrsCount;
  }

  if (attrsCount < 2) {
    throw CacheXmlException(
        "XML:Not enough attributes provided for a <server> - host and port "
        "required");
  }

  factory->addServer(host, std::stoi(port));
}

void CacheXmlParser::startPool(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <pool>. A pool cannot be created "
        "without a name");
  }
  auto factory =
      std::make_shared<PoolFactory>(m_cache->getPoolManager().createFactory());

  std::string poolName;

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (value.empty()) {
      throw CacheXmlException("XML: No value provided for attribute: " + name);
    }

    if (NAME == name) {
      poolName = std::move(value);
    } else {
      setPoolInfo(factory.get(), name.c_str(), value.c_str());
    }
  }

  if (poolName.empty()) {
    throw CacheXmlException(
        "XML:No attributes provided for a <pool> - at least the name is "
        "required");
  }

  auto poolxml = std::make_shared<PoolXmlCreation>(poolName, factory);

  _stack.push(poolxml);
  _stack.push(factory);
}

void CacheXmlParser::endPool() {
  _stack.pop();  // remove factory
  auto poolxml = std::static_pointer_cast<PoolXmlCreation>(_stack.top());
  _stack.pop();  // remove pool
  m_cacheCreation->addPool(poolxml);
}

void CacheXmlParser::setPoolInfo(PoolFactory* factory, const char* name,
                                 const char* value) {
  using apache::geode::client::equal_ignore_case;
  using apache::geode::internal::chrono::duration::from_string;

  if (strcmp(name, FREE_CONNECTION_TIMEOUT) == 0) {
    factory->setFreeConnectionTimeout(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, MULTIUSER_SECURE_MODE) == 0) {
    if (equal_ignore_case(value, "true")) {
      factory->setMultiuserAuthentication(true);
    } else {
      factory->setMultiuserAuthentication(false);
    }
  } else if (strcmp(name, IDLE_TIMEOUT) == 0) {
    factory->setIdleTimeout(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, LOAD_CONDITIONING_INTERVAL) == 0) {
    factory->setLoadConditioningInterval(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, MAX_CONNECTIONS) == 0) {
    factory->setMaxConnections(atoi(value));
  } else if (strcmp(name, MIN_CONNECTIONS) == 0) {
    factory->setMinConnections(atoi(value));
  } else if (strcmp(name, PING_INTERVAL) == 0) {
    factory->setPingInterval(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, UPDATE_LOCATOR_LIST_INTERVAL) == 0) {
    factory->setUpdateLocatorListInterval(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, READ_TIMEOUT) == 0) {
    factory->setReadTimeout(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, RETRY_ATTEMPTS) == 0) {
    factory->setRetryAttempts(atoi(value));
  } else if (strcmp(name, SERVER_GROUP) == 0) {
    factory->setServerGroup(value);
  } else if (strcmp(name, SOCKET_BUFFER_SIZE) == 0) {
    factory->setSocketBufferSize(atoi(value));
  } else if (strcmp(name, STATISTIC_INTERVAL) == 0) {
    factory->setStatisticInterval(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, SUBSCRIPTION_ACK_INTERVAL) == 0) {
    factory->setSubscriptionAckInterval(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, SUBSCRIPTION_ENABLED) == 0) {
    if (equal_ignore_case(value, "true")) {
      factory->setSubscriptionEnabled(true);
    } else {
      factory->setSubscriptionEnabled(false);
    }
  } else if (strcmp(name, SUBSCRIPTION_MTT) == 0) {
    factory->setSubscriptionMessageTrackingTimeout(
        from_string<std::chrono::milliseconds>(std::string(value)));
  } else if (strcmp(name, SUBSCRIPTION_REDUNDANCY) == 0) {
    factory->setSubscriptionRedundancy(atoi(value));
  } else if (strcmp(name, THREAD_LOCAL_CONNECTIONS) == 0) {
    if (equal_ignore_case(value, "true")) {
      factory->setThreadLocalConnections(true);
    } else {
      factory->setThreadLocalConnections(false);
    }
  } else if (strcmp(name, PR_SINGLE_HOP_ENABLED) == 0) {
    if (equal_ignore_case(value, "true")) {
      factory->setPRSingleHopEnabled(true);
    } else {
      factory->setPRSingleHopEnabled(false);
    }
  } else {
    throw CacheXmlException("XML:Unrecognized pool attribute " +
                            std::string(name));
  }
}

/**
 * When a <code>region</code> element is first encountered, we
 * create a {@link RegionCreation} and push it on the _stack.
 * An {@link RegionAttributesFactory }is also created and puhed on _stack.
 */
void CacheXmlParser::startRegion(const xmlChar** atts, bool isRoot) {
  int attrsCount = 0;
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <region>. A region cannot be created "
        "without a name");
  }
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount < 2 || attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for a <region>");
  }

  std::string regionName;
  std::string refid;

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if ("name" == name) {
      regionName = value;
    } else if ("refid" == name) {
      refid = value;
    } else {
      throw CacheXmlException("XML:<region> does not contain the attribute :" +
                              name);
    }
  }

  if (regionName.empty()) {
    throw CacheXmlException(
        "XML:The attribute name of <region> should be specified and cannot be "
        "empty");
  }

  auto region = std::make_shared<RegionXmlCreation>(regionName, isRoot);
  if (!region) {
    throw UnknownException("CacheXmlParser::startRegion:Out of memeory");
  }

  _stack.push(region);

  RegionAttributesFactory regionAttributesFactory;
  if (!refid.empty()) {
    if (namedRegions.find(refid) != namedRegions.end()) {
      regionAttributesFactory = RegionAttributesFactory(namedRegions[refid]);
    } else {
      throw CacheXmlException("XML:referenced named attribute '" + refid +
                              "' does not exist.");
    }
  }

  region->setAttributes(regionAttributesFactory.create());
}

void CacheXmlParser::startSubregion(const xmlChar** atts) {
  startRegion(atts, false);
}

void CacheXmlParser::startRootRegion(const xmlChar** atts) {
  startRegion(atts, true);
}

void CacheXmlParser::startRegionAttributes(const xmlChar** atts) {
  bool isDistributed = false;
  bool isTCR = false;
  std::shared_ptr<RegionAttributesFactory> regionAttributesFactory = nullptr;
  if (atts) {
    int attrsCount = 0;
    while (atts[attrsCount]) ++attrsCount;
    if (attrsCount > 24)  // Remember to change this when the number changes
    {
      throw CacheXmlException(
          "XML:Number of attributes provided for <region-attributes> are more");
    }

    std::string refid;

    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

      if (value.empty()) {
        throw CacheXmlException(
            "XML:In the <region-attributes> element attribute " + name +
            " can be set to empty string. It should either have a "
            "value or the attribute should be removed. In the latter case "
            "the default value will be set");
      }

      if (ID == name) {
        auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
        region->setAttrId(value);
      } else if (REFID == name) {
        refid = std::move(value);
      }
    }

    if (refid.empty()) {
      auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
      regionAttributesFactory =
          std::make_shared<RegionAttributesFactory>(region->getAttributes());
    } else {
      if (namedRegions.find(refid) != namedRegions.end()) {
        regionAttributesFactory =
            std::make_shared<RegionAttributesFactory>(namedRegions[refid]);
      } else {
        throw CacheXmlException("XML:referenced named attribute '" + refid +
                                "' does not exist.");
      }
    }

    if (!regionAttributesFactory) {
      throw UnknownException(
          "CacheXmlParser::startRegionAttributes:Out of memeory");
    }

    _stack.push(regionAttributesFactory);

    for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
      auto name = std::string(reinterpret_cast<const char*>(atts[i]));
      auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

      if (ID == name || REFID == name) {
        continue;
      } else if (CLIENT_NOTIFICATION_ENABLED == name) {
        bool flag = false;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if ("false" == value) {
          flag = false;
        } else if ("true" == value) {
          flag = true;
        } else {
          throw CacheXmlException(
              "XML: " + value +
              " is not a valid name for the attribute <client-notification>");
        }
        if (m_poolFactory) {
          m_poolFactory->setSubscriptionEnabled(flag);
        }
      } else if (INITIAL_CAPACITY == name) {
        regionAttributesFactory->setInitialCapacity(std::stoi(value));
      } else if (CONCURRENCY_LEVEL == name) {
        regionAttributesFactory->setConcurrencyLevel(std::stoi(value));
      } else if (LOAD_FACTOR == name) {
        regionAttributesFactory->setLoadFactor(std::stof(value));
      } else if (CACHING_ENABLED == name) {
        bool flag = false;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if ("false" == value) {
          flag = false;
        } else if ("true" == value) {
          flag = true;
        } else {
          throw CacheXmlException(
              "XML: " + value +
              " is not a valid name for the attribute <caching-enabled>");
        }
        regionAttributesFactory->setCachingEnabled(flag);
      } else if (LRU_ENTRIES_LIMIT == name) {
        regionAttributesFactory->setLruEntriesLimit(std::stoi(value));
      } else if (DISK_POLICY == name) {
        auto diskPolicy = apache::geode::client::DiskPolicyType::NONE;
        if (OVERFLOWS == value) {
          diskPolicy = apache::geode::client::DiskPolicyType::OVERFLOWS;
        } else if (PERSIST == value) {
          throw IllegalStateException("Persistence feature is not supported");
        } else if (NONE == value) {
          diskPolicy = apache::geode::client::DiskPolicyType::NONE;
        } else {
          throw CacheXmlException(
              "XML: " + value +
              " is not a valid name for the attribute <disk-policy>");
        }
        regionAttributesFactory->setDiskPolicy(diskPolicy);
      } else if (ENDPOINTS == name) {
        if (m_poolFactory) {
          for (auto&& endPoint : parseEndPoints(name)) {
            m_poolFactory->addServer(endPoint.first, endPoint.second);
          }
        }
        isTCR = true;
      } else if (POOL_NAME == name) {
        regionAttributesFactory->setPoolName(value);
        isTCR = true;
      } else if (CLONING_ENABLED == name) {
        bool flag = false;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if ("false" == value) {
          flag = false;
        } else if ("true" == value) {
          flag = true;
        } else {
          throw CacheXmlException(
              "XML: " + value +
              " is not a valid value for the attribute <cloning-enabled>");
        }
        regionAttributesFactory->setCloningEnabled(flag);
        isTCR = true;
      } else if (CONCURRENCY_CHECKS_ENABLED == name) {
        bool flag = false;
        std::transform(value.begin(), value.end(), value.begin(), ::tolower);
        if ("false" == value) {
          flag = false;
        } else if ("true" == value) {
          flag = true;
        } else {
          throw CacheXmlException("XML: " + value +
                                  " is not a valid value for the attribute "
                                  "<concurrency-checks-enabled>");
        }
        regionAttributesFactory->setConcurrencyChecksEnabled(flag);
      }
    }  // for loop
  }    // atts is nullptr
  else {
    auto region = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
    regionAttributesFactory =
        std::make_shared<RegionAttributesFactory>(region->getAttributes());
    _stack.push(regionAttributesFactory);
  }

  if (isDistributed && isTCR) {
    /* we don't allow DR+TCR at current stage according to sudhir */
    throw CacheXmlException(
        "XML:endpoints cannot be defined for distributed region.\n");
  }
}

void CacheXmlParser::endRegionAttributes() {
  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  _stack.pop();
  if (!regionAttributesFactory) {
    throw UnknownException(
        "CacheXmlParser::endRegion:RegionAttributesFactory is null");
  }

  auto regionAttributes = regionAttributesFactory->create();

  auto regionPtr = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
  if (!regionPtr) {
    throw UnknownException("CacheXmlParser::endRegion:Region is null");
  }

  std::string id = regionPtr->getAttrId();
  if (id != "") {
    namedRegions[id] = regionAttributes;
  }

  regionPtr->setAttributes(regionAttributes);
}

/**
 * When a <code>expiration-attributes</code> element is first
 * encountered, we create an {@link ExpirationAttibutes} object from
 * the element's attributes and push it on the _stack.
 */
void CacheXmlParser::startExpirationAttributes(const xmlChar** atts) {
  using apache::geode::internal::chrono::duration::from_string;

  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <expiration-attributes> ");
  }
  m_flagExpirationAttribute = true;
  size_t attrsCount = 0;
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for "
        "<expirartion-attributes>");
  }
  std::string timeOut;
  ExpirationAction expire = ExpirationAction::INVALID_ACTION;
  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (TIMEOUT == name) {
      if (value.empty()) {
        throw CacheXmlException(
            "XML:Value for attribute <timeout> needs to be specified");
      }
      timeOut = value;
    } else if (ACTION == name) {
      if (value.empty()) {
        throw CacheXmlException(
            "XML:The attribute <action> of <expiration-attributes> cannot be "
            "set to empty string. It should either have a value or the "
            "attribute should be removed. In the latter case the default value "
            "will be set");
      } else if (INVALIDATE == value) {
        expire = ExpirationAction::INVALIDATE;
      } else if (DESTROY == value) {
        expire = ExpirationAction::DESTROY;
      } else if (LOCAL_INVALIDATE == value) {
        expire = ExpirationAction::LOCAL_INVALIDATE;
      } else if (LOCAL_DESTROY == value) {
        expire = ExpirationAction::LOCAL_DESTROY;
      } else {
        throw CacheXmlException(
            "XML: " + value +
            " is not a valid value for the attribute <action>");
      }
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in "
          "<expiration-attributes>: " +
          value);
    }
  }
  if (timeOut.empty()) {
    throw CacheXmlException(
        "XML:The attribute <timeout> not specified in "
        "<expiration-attributes>.");
  }
  auto timeOutSeconds = from_string<std::chrono::seconds>(timeOut);

  auto expireAttr =
      std::make_shared<ExpirationAttributes>(timeOutSeconds, expire);
  if (!expireAttr) {
    throw UnknownException(
        "CacheXmlParser::startExpirationAttributes:Out of memory");
  }
  expireAttr->setAction(expire);

  _stack.push(expireAttr);
}
void CacheXmlParser::startPersistenceManager(const xmlChar** atts) {
  int attrsCount = 0;
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <persistence-manager>");
  }
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for "
        "<persistence-manager>");
  }
  std::string libraryName;
  std::string libraryFunctionName;
  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));
    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the "
                              "<persistence-manager>");
    }

    if (LIBRARY_NAME == name) {
      libraryName = std::move(value);
    } else if (LIBRARY_FUNCTION_NAME == name) {
      libraryFunctionName = std::move(value);
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <persistence-manager>: " +
          value);
    }
  }
  if (libraryFunctionName.empty()) {
    throw CacheXmlException(
        "XML:Library function name not specified in the <persistence-manager>");
  }

  try {
    if (managedPersistenceManagerFn &&
        libraryFunctionName.find('.') != std::string::npos) {
      // this is a managed library
      (*managedPersistenceManagerFn)(libraryName.c_str(),
                                     libraryFunctionName.c_str());
    } else {
      getFactoryFunc(libraryName, libraryFunctionName);
    }
  } catch (IllegalArgumentException& ex) {
    throw CacheXmlException(ex.what());
  }

  _stack.emplace(std::make_shared<std::string>(std::move(libraryName)));
  _stack.emplace(std::make_shared<std::string>(std::move(libraryFunctionName)));
}

void CacheXmlParser::startPersistenceProperties(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException("XML:No attributes provided for <property>");
  }
  int attrsCount = 0;
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for <property>");
  } else {
    if (m_config == nullptr) {
      m_config = Properties::create();
    }
  }
  std::string propName;
  std::string propValue;
  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the "
                              "<property>");
    }

    if ("name" == name) {
      propName = value;
    } else if ("value" == name) {
      propValue = value;
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <property>: " + name);
    }
  }
  if (propName.empty()) {
    throw CacheXmlException(
        "XML:attribute <name> needs to be specified in the <property>");
  }
  if (propValue.empty()) {
    throw CacheXmlException(
        "XML:attribute <value> needs to be  specified in the <property>");
  }
  m_config->insert(propName, propValue);
}

void CacheXmlParser::startCacheLoader(const xmlChar** atts) {
  std::string libraryName;
  std::string libraryFunctionName;
  int attrsCount = 0;
  if (!atts) {
    throw CacheXmlException("XML:No attributes provided for <cache-loader>");
  }
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for <cache-loader>");
  }

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the "
                              "<cache-loader>");
    }

    if (LIBRARY_NAME == name) {
      libraryName = std::move(value);
    } else if (LIBRARY_FUNCTION_NAME == name) {
      libraryFunctionName = std::move(value);
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <cache-loader> : " + name);
    }
  }
  if (libraryFunctionName.empty()) {
    throw CacheXmlException(
        "XML:<library-function-name> not specified in <cache-loader>");
  }

  try {
    if (managedCacheLoaderFn &&
        libraryFunctionName.find('.') != std::string::npos) {
      // this is a managed library
      (*managedCacheLoaderFn)(libraryName.c_str(), libraryFunctionName.c_str());
    } else {
      getFactoryFunc(libraryName, libraryFunctionName);
    }
  } catch (IllegalArgumentException& ex) {
    throw CacheXmlException(ex.what());
  }

  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  regionAttributesFactory->setCacheLoader(libraryName, libraryFunctionName);
}

void CacheXmlParser::startCacheListener(const xmlChar** atts) {
  std::string libraryName;
  std::string libraryFunctionName;
  int attrsCount = 0;
  if (!atts) {
    throw CacheXmlException("XML:No attributes provided for <cache-listener>");
  }
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for <cache-listener>");
  }

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the "
                              "<cache-listener>");
    }

    if (LIBRARY_NAME == name) {
      libraryName = std::move(value);
    } else if (LIBRARY_FUNCTION_NAME == name) {
      libraryFunctionName = std::move(value);
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <cache-listener> : " +
          name);
    }
  }
  if (libraryFunctionName.empty()) {
    throw CacheXmlException(
        "XML:Library function name not specified in <cache-listener>");
  }

  try {
    if (managedCacheListenerFn &&
        libraryFunctionName.find('.') != std::string::npos) {
      // this is a managed library
      (*managedCacheListenerFn)(libraryName.c_str(),
                                libraryFunctionName.c_str());
    } else {
      getFactoryFunc(libraryName, libraryFunctionName);
    }
  } catch (IllegalArgumentException& ex) {
    throw CacheXmlException(ex.what());
  }

  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  regionAttributesFactory->setCacheListener(libraryName, libraryFunctionName);
}

void CacheXmlParser::startPartitionResolver(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException(
        "XML:No attributes provided for <partition-resolver> ");
  }

  int attrsCount = 0;
  while (atts[attrsCount]) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for "
        "<partition-resolver>");
  }

  std::string libraryName;
  std::string libraryFunctionName;
  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the "
                              "<cache-listener>");
    }

    if (LIBRARY_NAME == name) {
      libraryName = std::move(value);
    } else if (LIBRARY_FUNCTION_NAME == name) {
      libraryFunctionName = std::move(value);
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <partition-resolver>: " +
          value);
    }
  }
  if (libraryFunctionName.empty()) {
    throw CacheXmlException(
        "XML:Library function name not specified in <partition-resolver> ");
  }

  try {
    if (managedPartitionResolverFn != nullptr &&
        libraryFunctionName.find('.') != std::string::npos) {
      // this is a managed library
      (*managedPartitionResolverFn)(libraryName.c_str(),
                                    libraryFunctionName.c_str());
    } else {
      getFactoryFunc(libraryName, libraryFunctionName);
    }
  } catch (IllegalArgumentException& ex) {
    throw CacheXmlException(ex.what());
  }

  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  regionAttributesFactory->setPartitionResolver(libraryName,
                                                libraryFunctionName);
}

void CacheXmlParser::startCacheWriter(const xmlChar** atts) {
  if (!atts) {
    throw CacheXmlException("XML:No attributes provided for <cache-writer>");
  }

  int attrsCount = 0;
  while (atts[attrsCount] != nullptr) ++attrsCount;
  if (attrsCount > 4) {
    throw CacheXmlException(
        "XML:Incorrect number of attributes provided for <cache-writer>");
  }

  std::string libraryName;
  std::string libraryFunctionName;

  for (size_t i = 0; atts[i] && atts[i + 1]; i += 2) {
    auto name = std::string(reinterpret_cast<const char*>(atts[i]));
    auto value = std::string(reinterpret_cast<const char*>(atts[i + 1]));

    if (value.empty()) {
      throw CacheXmlException("XML:Value for attribute <" + name +
                              "> needs to be specified in the <cache-writer>");
    }

    if (LIBRARY_NAME == name) {
      libraryName = std::move(value);
    } else if (LIBRARY_FUNCTION_NAME == name) {
      libraryFunctionName = std::move(value);
    } else {
      throw CacheXmlException(
          "XML:Incorrect attribute name specified in <cache-writer>: " + value);
    }
  }
  if (libraryFunctionName.empty()) {
    throw CacheXmlException(
        "XML:Library function name not specified in the <cache-writer>");
  }

  try {
    if (managedCacheWriterFn &&
        libraryFunctionName.find('.') != std::string::npos) {
      // this is a managed library
      (*managedCacheWriterFn)(libraryName.c_str(), libraryFunctionName.c_str());
    } else {
      getFactoryFunc(libraryName, libraryFunctionName);
    }
  } catch (IllegalArgumentException& ex) {
    throw CacheXmlException(ex.what());
  }

  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  regionAttributesFactory->setCacheWriter(libraryName, libraryFunctionName);
}

/**
 * After popping the current <code>RegionXmlCreation</code> off the
 * _stack, if the element on top of the _stack is a
 * <code>RegionXmlCreation</code>, then it is the parent region.
 */
void CacheXmlParser::endRegion(bool isRoot) {
  auto regionPtr = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
  _stack.pop();
  if (isRoot) {
    if (!_stack.empty()) {
      throw CacheXmlException("Xml file has incorrectly nested region tags");
    }
    if (!m_cacheCreation) {
      throw CacheXmlException(
          "XML: Element <cache> was not provided in the xml");
    }

    m_cacheCreation->addRootRegion(regionPtr);
  } else {
    if (_stack.empty()) {
      throw CacheXmlException("Xml file has incorrectly nested region tags");
    }
    auto parent = std::static_pointer_cast<RegionXmlCreation>(_stack.top());
    parent->addSubregion(regionPtr);
  }
}

void CacheXmlParser::endSubregion() { endRegion(false); }

void CacheXmlParser::endRootRegion() { endRegion(true); }

/**
 * When a <code>cache</code> element is finished
 */
void CacheXmlParser::endCache() {}

/**
 * When a <code>region-time-to-live</code> element is finished, the
 * {@link ExpirationAttributes} are on top of the _stack followed by
 * the {@link RegionAttributesFactory} to which the expiration
 * attributes are assigned.
 */
void CacheXmlParser::endRegionTimeToLive() {
  if (!m_flagExpirationAttribute) {
    throw CacheXmlException(
        "XML: <region-time-to-live> cannot be without a "
        "<expiration-attributes>");
  }

  auto expireAttr =
      std::static_pointer_cast<ExpirationAttributes>(_stack.top());
  _stack.pop();

  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  regionAttributesFactory->setRegionTimeToLive(expireAttr->getAction(),
                                               expireAttr->getTimeout());
  m_flagExpirationAttribute = false;
}

/**
 * When a <code>region-idle-time</code> element is finished, the
 * {@link ExpirationAttributes} are on top of the _stack followed by
 * the {@link RegionAttributesFactory} to which the expiration
 * attributes are assigned.
 */
void CacheXmlParser::endRegionIdleTime() {
  if (!m_flagExpirationAttribute) {
    throw CacheXmlException(
        "XML: <region-idle-time> cannot be without <expiration-attributes>");
  }
  auto expireAttr =
      std::static_pointer_cast<ExpirationAttributes>(_stack.top());
  _stack.pop();
  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());

  regionAttributesFactory->setRegionIdleTimeout(expireAttr->getAction(),
                                                expireAttr->getTimeout());
  m_flagExpirationAttribute = false;
}

/**
 * When a <code>entry-time-to-live</code> element is finished, the
 * {@link ExpirationAttributes} are on top of the _stack followed by
 * the {@link RegionAttributesFactory} to which the expiration
 * attributes are assigned.
 */
void CacheXmlParser::endEntryTimeToLive() {
  if (!m_flagExpirationAttribute) {
    throw CacheXmlException(
        "XML: <entry-time-to-live> cannot be without <expiration-attributes>");
  }
  auto expireAttr =
      std::static_pointer_cast<ExpirationAttributes>(_stack.top());
  _stack.pop();
  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());

  regionAttributesFactory->setEntryTimeToLive(expireAttr->getAction(),
                                              expireAttr->getTimeout());
  m_flagExpirationAttribute = false;
}

/**
 * When a <code>entry-idle-time</code> element is finished, the
 * {@link ExpirationAttributes} are on top of the _stack followed by
 * the {@link RegionAttributesFactory} to which the expiration
 * attributes are assigned.
 */
void CacheXmlParser::endEntryIdleTime() {
  if (!m_flagExpirationAttribute) {
    throw CacheXmlException(
        "XML: <entry-idle-time> cannot be without <expiration-attributes>");
  }
  auto expireAttr =
      std::static_pointer_cast<ExpirationAttributes>(_stack.top());
  _stack.pop();
  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  // TODO GEODE-3136: consider string parser here.
  regionAttributesFactory->setEntryIdleTimeout(expireAttr->getAction(),
                                               expireAttr->getTimeout());
  m_flagExpirationAttribute = false;
}

/**
 * When persistence-manager attributes is finished, it will set the attribute
 * factory.
 */
void CacheXmlParser::endPersistenceManager() {
  std::shared_ptr<std::string> libraryFunctionName =
      std::static_pointer_cast<std::string>(_stack.top());
  _stack.pop();
  std::shared_ptr<std::string> libraryName =
      std::static_pointer_cast<std::string>(_stack.top());
  _stack.pop();
  auto regionAttributesFactory =
      std::static_pointer_cast<RegionAttributesFactory>(_stack.top());
  if (m_config != nullptr) {
    regionAttributesFactory->setPersistenceManager(
        libraryName->c_str(), libraryFunctionName->c_str(), m_config);
    m_config = nullptr;
  } else {
    regionAttributesFactory->setPersistenceManager(
        libraryName->c_str(), libraryFunctionName->c_str());
  }
}

CacheXmlParser::~CacheXmlParser() { _GEODE_SAFE_DELETE(m_cacheCreation); }

void CacheXmlParser::setError(const std::string& err) { m_error = err; }

const std::string& CacheXmlParser::getError() const { return m_error; }

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