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

#include <geode/internal/geode_globals.hpp>
#include <geode/Cache.hpp>
#include <geode/FunctionService.hpp>
#include <geode/AuthenticatedView.hpp>
#include <geode/PoolManager.hpp>

#include "DistributedSystemImpl.hpp"
#include "CacheXmlParser.hpp"
#include "CacheRegionHelper.hpp"
#include "CacheImpl.hpp"
#include "UserAttributes.hpp"
#include "ProxyRegion.hpp"
#include "ProxyRemoteQueryService.hpp"
#include "FunctionServiceImpl.hpp"
#include "ThinClientPoolDM.hpp"

namespace apache {
namespace geode {
namespace client {

/**
 * Indicates if this cache has been closed.
 * After a new cache object is created, this method returns false;
 * After the close is called on this cache object, this method
 * returns true.
 *
 * @return true, if this cache is closed; false, otherwise
 */
bool AuthenticatedView::isClosed() const { return m_isAuthenticatedViewClosed; }

/**
 * Terminates this object cache and releases all the local resources.
 * After this cache is closed, any further
 * method call on this cache or any region object will throw
 * <code>CacheClosedException</code>, unless otherwise noted.
 * @param keepalive whether to keep the durable client's queue
 * @throws CacheClosedException,  if the cache is already closed.
 */
void AuthenticatedView::close() {
  LOGDEBUG("AuthenticatedView::close: isAuthenticatedViewClosed = %d",
           m_isAuthenticatedViewClosed);
  if (!m_isAuthenticatedViewClosed) {
    if (m_remoteQueryService != nullptr) {
      ProxyRemoteQueryService* prqs =
          static_cast<ProxyRemoteQueryService*>(m_remoteQueryService.get());
      prqs->closeCqs(false);
    }

    GuardUserAttributes gua(this);
    m_isAuthenticatedViewClosed = true;
    m_userAttributes->unSetCredentials();
    // send message to server
    auto userAttachedPool = m_userAttributes->getPool();
    auto pool = m_cacheImpl->getCache()->getPoolManager().find(
        userAttachedPool->getName());
    if (pool != nullptr && pool.get() == userAttachedPool.get()) {
      auto poolDM = std::static_pointer_cast<ThinClientPoolDM>(pool);
      if (!poolDM->isDestroyed()) {
        poolDM->sendUserCacheCloseMessage(false);
      }
    }
    return;
  }
  throw IllegalStateException("User cache has been closed.");
}
std::shared_ptr<Region> AuthenticatedView::getRegion(
    const std::string& path) const {
  LOGDEBUG("AuthenticatedView::getRegion:");

  if (!m_isAuthenticatedViewClosed) {
    std::shared_ptr<Region> result;

    if (m_cacheImpl != nullptr && !m_cacheImpl->isClosed()) {
      result = m_cacheImpl->getRegion(path);
    }

    if (result != nullptr) {
      auto userAttachedPool = m_userAttributes->getPool();
      auto pool = m_cacheImpl->getCache()->getPoolManager().find(
          result->getAttributes().getPoolName());
      if (pool != nullptr && pool.get() == userAttachedPool.get() &&
          !pool->isDestroyed()) {
        return std::make_shared<ProxyRegion>(
            const_cast<AuthenticatedView&>(*this),
            std::static_pointer_cast<RegionInternal>(result));
      }
      throw IllegalArgumentException(
          "The Region argument is not attached with the pool, which used to "
          "create this user cache.");
    }

    return result;
  }
  throw IllegalStateException("User cache has been closed.");
}

/**
 * Returns a set of root regions in the cache. Does not cause any
 * shared regions to be mapped into the cache. This set is a snapshot and
 * is not backed by the Cache. The regions passed in are cleared.
 *
 * @param regions the region collection object containing the returned set of
 * regions when the function returns
 */
std::shared_ptr<QueryService> AuthenticatedView::getQueryService() {
  if (!m_isAuthenticatedViewClosed) {
    if (m_remoteQueryService != nullptr) return m_remoteQueryService;
    auto prqsPtr = std::make_shared<ProxyRemoteQueryService>(this);
    m_remoteQueryService = prqsPtr;
    return prqsPtr;
  }
  throw IllegalStateException("User cache has been closed.");
}

std::vector<std::shared_ptr<Region>> AuthenticatedView::rootRegions() const {
  LOGDEBUG("AuthenticatedView::rootRegions:");

  std::vector<std::shared_ptr<Region>> regions;

  if (!m_isAuthenticatedViewClosed && m_cacheImpl && !m_cacheImpl->isClosed()) {
    // this can cause issue when pool attached with region in multiuserSecure
    // mode
    auto tmp = m_cacheImpl->rootRegions();
    regions.reserve(tmp.size());

    for (const auto& reg : tmp) {
      if (m_userAttributes->getPool()->getName() ==
          reg->getAttributes().getPoolName()) {
        auto pRegion = std::make_shared<ProxyRegion>(
            const_cast<AuthenticatedView&>(*this),
            std::static_pointer_cast<RegionInternal>(reg));
        regions.push_back(pRegion);
      }
    }
  }

  return regions;
}

AuthenticatedView::AuthenticatedView(std::shared_ptr<Properties> credentials,
                                     std::shared_ptr<Pool> pool,
                                     CacheImpl* cacheImpl)
    : m_userAttributes(
          std::make_shared<UserAttributes>(credentials, pool, this)),
      m_isAuthenticatedViewClosed(false),
      m_remoteQueryService(nullptr),
      m_cacheImpl(cacheImpl) {}

AuthenticatedView::~AuthenticatedView() {}

PdxInstanceFactory AuthenticatedView::createPdxInstanceFactory(
    const std::string& className) const {
  return PdxInstanceFactory(className, m_cacheImpl->getCachePerfStats(),
                            *m_cacheImpl->getPdxTypeRegistry(), *m_cacheImpl,
                            m_cacheImpl->getDistributedSystem()
                                .getSystemProperties()
                                .getEnableTimeStatistics());
}
}  // namespace client
}  // namespace geode
}  // namespace apache
