/*
 * 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 <string>
#include <cstdlib>

#include <ace/DLL.h>
#include <ace/OS.h>

#include <geode/Cache.hpp>
#include <geode/DataOutput.hpp>
#include <geode/DataInput.hpp>
#include <geode/Properties.hpp>

#include "Utils.hpp"
#include "CacheXmlParser.hpp"

namespace apache {
namespace geode {
namespace client {

RegionAttributes::RegionAttributes()
    : Serializable(),
      m_regionTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
      m_regionIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE),
      m_entryTimeToLiveExpirationAction(ExpirationAction::INVALIDATE),
      m_entryIdleTimeoutExpirationAction(ExpirationAction::INVALIDATE),
      m_lruEvictionAction(ExpirationAction::LOCAL_DESTROY),
      m_lruEntriesLimit(0),
      m_caching(true),
      m_maxValueDistLimit(100 * 1024),
      m_entryIdleTimeout(0),
      m_entryTimeToLive(0),
      m_regionIdleTimeout(0),
      m_regionTimeToLive(0),
      m_initialCapacity(10000),
      m_loadFactor(0.75),
      m_concurrencyLevel(16),
      m_diskPolicy(DiskPolicyType::NONE),
      m_clientNotificationEnabled(false),
      m_persistenceProperties(nullptr),
      m_persistenceManager(nullptr),
      m_isClonable(false),
      m_isConcurrencyChecksEnabled(true) {}

RegionAttributes::~RegionAttributes() noexcept = default;

namespace impl {

/**
 * lib should be in the form required by ACE_DLL, typically just like specifying
 * a
 * lib in java System.loadLibrary( "x" ); Where x is a component of the name
 * lib<x>.so on unix, or <x>.dll on windows.
 */
void* getFactoryFunc(const std::string& lib, const std::string& funcName) {
  ACE_DLL dll;
  if (dll.open(lib.c_str(), ACE_DEFAULT_SHLIB_MODE, 0) == -1) {
    throw IllegalArgumentException("cannot open library: " + lib);
  }
  void* func = dll.symbol(funcName.c_str());
  if (func == nullptr) {
    throw IllegalArgumentException("cannot find factory function " + funcName +
                                   " in library " + lib);
  }
  return func;
}

}  // namespace impl

std::shared_ptr<CacheLoader> RegionAttributes::getCacheLoader() const {
  if (!m_cacheLoader && !m_cacheLoaderLibrary.empty()) {
    if (CacheXmlParser::managedCacheLoaderFn &&
        m_cacheLoaderFactory.find('.') != std::string::npos) {
      // this is a managed library
      m_cacheLoader.reset((*CacheXmlParser::managedCacheLoaderFn)(
          m_cacheLoaderLibrary.c_str(), m_cacheLoaderFactory.c_str()));
    } else {
      CacheLoader* (*funcptr)();
      funcptr = reinterpret_cast<CacheLoader* (*)()>(
          apache::geode::client::impl::getFactoryFunc(m_cacheLoaderLibrary,
                                                      m_cacheLoaderFactory));
      m_cacheLoader.reset(funcptr());
    }
  }
  return m_cacheLoader;
}

std::shared_ptr<CacheWriter> RegionAttributes::getCacheWriter() const {
  if (!m_cacheWriter && !m_cacheWriterLibrary.empty()) {
    if (CacheXmlParser::managedCacheWriterFn &&
        m_cacheWriterFactory.find('.') != std::string::npos) {
      // this is a managed library
      m_cacheWriter.reset((*CacheXmlParser::managedCacheWriterFn)(
          m_cacheWriterLibrary.c_str(), m_cacheWriterFactory.c_str()));
    } else {
      CacheWriter* (*funcptr)();
      funcptr = reinterpret_cast<CacheWriter* (*)()>(
          apache::geode::client::impl::getFactoryFunc(m_cacheWriterLibrary,
                                                      m_cacheWriterFactory));
      m_cacheWriter.reset(funcptr());
    }
  }
  return m_cacheWriter;
}

std::shared_ptr<CacheListener> RegionAttributes::getCacheListener() const {
  if (!m_cacheListener && !m_cacheListenerLibrary.empty()) {
    if (CacheXmlParser::managedCacheListenerFn &&
        m_cacheListenerFactory.find('.') != std::string::npos) {
      // this is a managed library
      m_cacheListener.reset((*CacheXmlParser::managedCacheListenerFn)(
          m_cacheListenerLibrary.c_str(), m_cacheListenerFactory.c_str()));
    } else {
      CacheListener* (*funcptr)();
      funcptr = reinterpret_cast<CacheListener* (*)()>(
          apache::geode::client::impl::getFactoryFunc(m_cacheListenerLibrary,
                                                      m_cacheListenerFactory));
      m_cacheListener.reset(funcptr());
    }
  }
  return m_cacheListener;
}

std::shared_ptr<PartitionResolver> RegionAttributes::getPartitionResolver() const {
  if (!m_partitionResolver && !m_partitionResolverLibrary.empty()) {
    if (CacheXmlParser::managedPartitionResolverFn &&
        m_partitionResolverFactory.find('.') != std::string::npos) {
      // this is a managed library
      m_partitionResolver.reset((*CacheXmlParser::managedPartitionResolverFn)(
          m_partitionResolverLibrary.c_str(),
          m_partitionResolverFactory.c_str()));
    } else {
      PartitionResolver* (*funcptr)();
      funcptr = reinterpret_cast<PartitionResolver* (*)()>(
          apache::geode::client::impl::getFactoryFunc(
              m_partitionResolverLibrary, m_partitionResolverFactory));
      m_partitionResolver.reset(funcptr());
    }
  }
  return m_partitionResolver;
}

std::shared_ptr<PersistenceManager> RegionAttributes::getPersistenceManager() const {
  if (!m_persistenceManager && !m_persistenceLibrary.empty()) {
    if (CacheXmlParser::managedPartitionResolverFn &&
        m_persistenceFactory.find('.') != std::string::npos) {
      // this is a managed library
      m_persistenceManager.reset((*CacheXmlParser::managedPersistenceManagerFn)(
          m_persistenceLibrary.c_str(), m_persistenceFactory.c_str()));
    } else {
      PersistenceManager* (*funcptr)();
      funcptr = reinterpret_cast<PersistenceManager* (*)()>(
          apache::geode::client::impl::getFactoryFunc(m_persistenceLibrary,
                                                      m_persistenceFactory));
      m_persistenceManager.reset(funcptr());
    }
  }
  return m_persistenceManager;
}

const std::string& RegionAttributes::getCacheLoaderFactory() const {
  return m_cacheLoaderFactory;
}

const std::string& RegionAttributes::getCacheWriterFactory() const {
  return m_cacheWriterFactory;
}

const std::string& RegionAttributes::getCacheListenerFactory() const {
  return m_cacheListenerFactory;
}

const std::string& RegionAttributes::getPartitionResolverFactory() const {
  return m_partitionResolverFactory;
}

const std::string& RegionAttributes::getPersistenceFactory() const {
  return m_persistenceFactory;
}
const std::string& RegionAttributes::getCacheLoaderLibrary() const {
  return m_cacheLoaderLibrary;
}

const std::string& RegionAttributes::getCacheWriterLibrary() const {
  return m_cacheWriterLibrary;
}

const std::string& RegionAttributes::getCacheListenerLibrary() const {
  return m_cacheListenerLibrary;
}

const std::string& RegionAttributes::getPartitionResolverLibrary() const {
  return m_partitionResolverLibrary;
}

const std::string& RegionAttributes::getEndpoints() const {
  return m_endpoints;
}

bool RegionAttributes::getClientNotificationEnabled() const {
  return m_clientNotificationEnabled;
}

const std::string& RegionAttributes::getPersistenceLibrary() const {
  return m_persistenceLibrary;
}

std::shared_ptr<Properties> RegionAttributes::getPersistenceProperties() const {
  return m_persistenceProperties;
}

std::chrono::seconds RegionAttributes::getRegionTimeToLive() const {
  return m_regionTimeToLive;
}

ExpirationAction RegionAttributes::getRegionTimeToLiveAction() const {
  return m_regionTimeToLiveExpirationAction;
}

std::chrono::seconds RegionAttributes::getRegionIdleTimeout() const {
  return m_regionIdleTimeout;
}

ExpirationAction RegionAttributes::getRegionIdleTimeoutAction() const {
  return m_regionIdleTimeoutExpirationAction;
}

std::chrono::seconds RegionAttributes::getEntryTimeToLive() const {
  return m_entryTimeToLive;
}

ExpirationAction RegionAttributes::getEntryTimeToLiveAction() const {
  return m_entryTimeToLiveExpirationAction;
}

std::chrono::seconds RegionAttributes::getEntryIdleTimeout() const {
  return m_entryIdleTimeout;
}

ExpirationAction RegionAttributes::getEntryIdleTimeoutAction() const {
  return m_entryIdleTimeoutExpirationAction;
}

int RegionAttributes::getInitialCapacity() const { return m_initialCapacity; }

float RegionAttributes::getLoadFactor() const { return m_loadFactor; }

uint8_t RegionAttributes::getConcurrencyLevel() const {
  return m_concurrencyLevel;
}

ExpirationAction RegionAttributes::getLruEvictionAction() const {
  return m_lruEvictionAction;
}

uint32_t RegionAttributes::getLruEntriesLimit() const {
  return m_lruEntriesLimit;
}

DiskPolicyType RegionAttributes::getDiskPolicy() const {
  return m_diskPolicy;
}

std::shared_ptr<Serializable> RegionAttributes::createDeserializable() {
  return std::make_shared<RegionAttributes>();
}

int8_t RegionAttributes::getInternalId() const {
  return static_cast<int8_t>(DSCode::RegionAttributes);
}

namespace impl {

void writeBool(DataOutput& out, bool field) {
  out.write(static_cast<int8_t>(field ? 1 : 0));
}

void readBool(DataInput& in, bool* field) { *field = in.read() ? true : false; }

void writeString(DataOutput& out, const std::string& field) {
  out.writeBytes(reinterpret_cast<int8_t*>(const_cast<char*>(field.c_str())),
                 static_cast<uint32_t>(field.length()) + 1);
}

void readString(DataInput& in, std::string& field) {
  // length including null terminator
  auto len = in.readArrayLength();
  // currentBufferPosition is read-only and we are only reading, cast away const
  field = std::string(const_cast<char*>(reinterpret_cast<const char*>(
                          in.currentBufferPosition())),
                      len - 1);
  in.advanceCursor(len);
}

}  // namespace impl

void RegionAttributes::toData(DataOutput& out) const {
  out.writeInt(static_cast<int32_t>(m_regionTimeToLive.count()));
  out.writeInt(static_cast<int32_t>(m_regionTimeToLiveExpirationAction));
  out.writeInt(static_cast<int32_t>(m_regionIdleTimeout.count()));
  out.writeInt(static_cast<int32_t>(m_regionIdleTimeoutExpirationAction));
  out.writeInt(static_cast<int32_t>(m_entryTimeToLive.count()));
  out.writeInt(static_cast<int32_t>(m_entryTimeToLiveExpirationAction));
  out.writeInt(static_cast<int32_t>(m_entryIdleTimeout.count()));
  out.writeInt(static_cast<int32_t>(m_entryIdleTimeoutExpirationAction));
  out.writeInt(static_cast<int32_t>(m_initialCapacity));
  out.writeFloat(m_loadFactor);
  out.writeInt(static_cast<int32_t>(m_maxValueDistLimit));
  out.writeInt(static_cast<int32_t>(m_concurrencyLevel));
  out.writeInt(static_cast<int32_t>(m_lruEntriesLimit));
  out.writeInt(static_cast<int32_t>(m_lruEvictionAction));

  apache::geode::client::impl::writeBool(out, m_caching);
  apache::geode::client::impl::writeBool(out, m_clientNotificationEnabled);

  apache::geode::client::impl::writeString(out, m_cacheLoaderLibrary);
  apache::geode::client::impl::writeString(out, m_cacheLoaderFactory);
  apache::geode::client::impl::writeString(out, m_cacheWriterLibrary);
  apache::geode::client::impl::writeString(out, m_cacheWriterFactory);
  apache::geode::client::impl::writeString(out, m_cacheListenerLibrary);
  apache::geode::client::impl::writeString(out, m_cacheListenerFactory);
  apache::geode::client::impl::writeString(out, m_partitionResolverLibrary);
  apache::geode::client::impl::writeString(out, m_partitionResolverFactory);
  out.writeInt(static_cast<int32_t>(m_diskPolicy));
  apache::geode::client::impl::writeString(out, m_endpoints);
  apache::geode::client::impl::writeString(out, m_persistenceLibrary);
  apache::geode::client::impl::writeString(out, m_persistenceFactory);
  out.writeObject(m_persistenceProperties);
  apache::geode::client::impl::writeString(out, m_poolName);
  apache::geode::client::impl::writeBool(out, m_isConcurrencyChecksEnabled);
}

void RegionAttributes::fromData(DataInput& in) {
  m_regionTimeToLive = std::chrono::seconds(in.readInt32());
  m_regionTimeToLiveExpirationAction =
      static_cast<ExpirationAction>(in.readInt32());
  m_regionIdleTimeout = std::chrono::seconds(in.readInt32());
  m_regionIdleTimeoutExpirationAction =
      static_cast<ExpirationAction>(in.readInt32());
  m_entryTimeToLive = std::chrono::seconds(in.readInt32());
  m_entryTimeToLiveExpirationAction =
      static_cast<ExpirationAction>(in.readInt32());
  m_entryIdleTimeout = std::chrono::seconds(in.readInt32());
  m_entryIdleTimeoutExpirationAction =
      static_cast<ExpirationAction>(in.readInt32());
  m_initialCapacity = in.readInt32();
  m_loadFactor = in.readFloat();
  m_maxValueDistLimit = in.readInt32();
  m_concurrencyLevel = in.readInt32();
  m_lruEntriesLimit = in.readInt32();
  m_lruEvictionAction = static_cast<ExpirationAction>(in.readInt32());

  apache::geode::client::impl::readBool(in, &m_caching);
  apache::geode::client::impl::readBool(in, &m_clientNotificationEnabled);

  apache::geode::client::impl::readString(in, m_cacheLoaderLibrary);
  apache::geode::client::impl::readString(in, m_cacheLoaderFactory);
  apache::geode::client::impl::readString(in, m_cacheWriterLibrary);
  apache::geode::client::impl::readString(in, m_cacheWriterFactory);
  apache::geode::client::impl::readString(in, m_cacheListenerLibrary);
  apache::geode::client::impl::readString(in, m_cacheListenerFactory);
  apache::geode::client::impl::readString(in, m_partitionResolverLibrary);
  apache::geode::client::impl::readString(in, m_partitionResolverFactory);
  m_diskPolicy = static_cast<DiskPolicyType>(in.readInt32());
  apache::geode::client::impl::readString(in, m_endpoints);
  apache::geode::client::impl::readString(in, m_persistenceLibrary);
  apache::geode::client::impl::readString(in, m_persistenceFactory);
  m_persistenceProperties =
      std::dynamic_pointer_cast<Properties>(in.readObject());
  apache::geode::client::impl::readString(in, m_poolName);
  apache::geode::client::impl::readBool(in, &m_isConcurrencyChecksEnabled);
}

/** Return true if all the attributes are equal to those of other. */
bool RegionAttributes::operator==(const RegionAttributes& other) const {
  if (m_regionTimeToLive != other.m_regionTimeToLive) return false;
  if (m_regionTimeToLiveExpirationAction !=
      other.m_regionTimeToLiveExpirationAction) {
    return false;
  }
  if (m_regionIdleTimeout != other.m_regionIdleTimeout) return false;
  if (m_regionIdleTimeoutExpirationAction !=
      other.m_regionIdleTimeoutExpirationAction) {
    return false;
  }
  if (m_entryTimeToLive != other.m_entryTimeToLive) return false;
  if (m_entryTimeToLiveExpirationAction !=
      other.m_entryTimeToLiveExpirationAction) {
    return false;
  }
  if (m_entryIdleTimeout != other.m_entryIdleTimeout) return false;
  if (m_entryIdleTimeoutExpirationAction !=
      other.m_entryIdleTimeoutExpirationAction) {
    return false;
  }
  if (m_initialCapacity != other.m_initialCapacity) return false;
  if (m_loadFactor != other.m_loadFactor) return false;
  if (m_maxValueDistLimit != other.m_maxValueDistLimit) return false;
  if (m_concurrencyLevel != other.m_concurrencyLevel) return false;
  if (m_lruEntriesLimit != other.m_lruEntriesLimit) return false;
  if (m_lruEvictionAction != other.m_lruEvictionAction) return false;
  if (m_caching != other.m_caching) return false;
  if (m_clientNotificationEnabled != other.m_clientNotificationEnabled) {
    return false;
  }

  if (m_cacheLoaderLibrary != other.m_cacheLoaderLibrary) {
    return false;
  }
  if (m_cacheLoaderFactory != other.m_cacheLoaderFactory) {
    return false;
  }
  if (m_cacheWriterLibrary != other.m_cacheWriterLibrary) {
    return false;
  }
  if (m_cacheWriterFactory != other.m_cacheWriterFactory) {
    return false;
  }
  if (m_cacheListenerLibrary != other.m_cacheListenerLibrary) {
    return false;
  }
  if (m_cacheListenerFactory != other.m_cacheListenerFactory) {
    return false;
  }
  if (m_partitionResolverLibrary != other.m_partitionResolverLibrary) {
    return false;
  }
  if (m_partitionResolverFactory != other.m_partitionResolverFactory) {
    return false;
  }
  if (m_diskPolicy != other.m_diskPolicy) {
    return false;
  }
  if (m_endpoints != other.m_endpoints) {
    return false;
  }
  if (m_persistenceLibrary != other.m_persistenceLibrary) {
    return false;
  }
  if (m_persistenceFactory != other.m_persistenceFactory) {
    return false;
  }
  if (m_isConcurrencyChecksEnabled != other.m_isConcurrencyChecksEnabled) {
    return false;
  }

  return true;
}

/** Return true if any of the attributes are not equal to those of other. */
bool RegionAttributes::operator!=(const RegionAttributes& other) const {
  return !(*this == other);
}

/* Throws IllegalStateException when attributes targetted for use on a server do
 * not meet requirements. */
void RegionAttributes::validateSerializableAttributes() {
  if (m_cacheLoader != nullptr) {
    throw IllegalStateException(
        "CacheLoader must be set with setCacheLoader(library, factory) in "
        "members of type SERVER");
  }
  if (m_cacheWriter != nullptr) {
    throw IllegalStateException(
        "CacheWriter must be set with setCacheWriter(library, factory) in "
        "members of type SERVER");
  }
  if (m_cacheListener != nullptr) {
    throw IllegalStateException(
        "CacheListener must be set with setCacheListener(library, factory) in "
        "members of type SERVER");
  }
  if (m_partitionResolver != nullptr) {
    throw IllegalStateException(
        "PartitionResolver must be set with setPartitionResolver(library, "
        "factory) in members of type SERVER");
  }
  if (m_persistenceManager != nullptr) {
    throw IllegalStateException(
        "persistenceManager must be set with setPersistenceManager(library, "
        "factory,config) in members of type SERVER");
  }
}

void RegionAttributes::setCacheListener(const std::string& lib,
                                        const std::string& func) {
  m_cacheListenerLibrary = lib;
  m_cacheListenerFactory = func;
}

void RegionAttributes::setPartitionResolver(const std::string& lib,
                                            const std::string& func) {
  m_partitionResolverLibrary = lib;
  m_partitionResolverFactory = func;
}

void RegionAttributes::setCacheLoader(const std::string& lib,
                                      const std::string& func) {
  m_cacheLoaderLibrary = lib;
  m_cacheLoaderFactory = func;
}

void RegionAttributes::setCacheWriter(const std::string& lib,
                                      const std::string& func) {
  m_cacheWriterLibrary = lib;
  m_cacheWriterFactory = func;
}

void RegionAttributes::setPersistenceManager(
    const std::string& lib, const std::string& func,
    const std::shared_ptr<Properties>& config) {
  m_persistenceLibrary = lib;
  m_persistenceFactory = func;
  m_persistenceProperties = config;
}

void RegionAttributes::setEndpoints(const std::string& endpoints) {
  m_endpoints = endpoints;
}

void RegionAttributes::setPoolName(const std::string& poolName) {
  m_poolName = poolName;
}

void RegionAttributes::setCachingEnabled(bool enable) { m_caching = enable; }

void RegionAttributes::setLruEntriesLimit(int limit) {
  m_lruEntriesLimit = limit;
}
void RegionAttributes::setDiskPolicy(DiskPolicyType diskPolicy) {
  m_diskPolicy = diskPolicy;
}

void RegionAttributes::setCloningEnabled(bool isClonable) {
  m_isClonable = isClonable;
}

void RegionAttributes::setConcurrencyChecksEnabled(bool enable) {
  m_isConcurrencyChecksEnabled = enable;
}

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