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

#include <geode/ExceptionTypes.hpp>

#include "ErrType.hpp"
#include "util/Log.hpp"

namespace {

using apache::geode::client::AllConnectionsInUseException;
using apache::geode::client::AuthenticationFailedException;
using apache::geode::client::AuthenticationRequiredException;
using apache::geode::client::BufferSizeExceededException;
using apache::geode::client::CacheClosedException;
using apache::geode::client::CacheListenerException;
using apache::geode::client::CacheLoaderException;
using apache::geode::client::CacheProxyException;
using apache::geode::client::CacheServerException;
using apache::geode::client::CacheWriterException;
using apache::geode::client::CommitConflictException;
using apache::geode::client::ConcurrentModificationException;
using apache::geode::client::DiskFailureException;
using apache::geode::client::DuplicateDurableClientException;
using apache::geode::client::EntryDestroyedException;
using apache::geode::client::EntryExistsException;
using apache::geode::client::EntryNotFoundException;
using apache::geode::client::FunctionExecutionException;
using apache::geode::client::GeodeIOException;
using apache::geode::client::IllegalArgumentException;
using apache::geode::client::IllegalStateException;
using apache::geode::client::LeaseExpiredException;
using apache::geode::client::LowMemoryException;
using apache::geode::client::MessageException;
using apache::geode::client::NoAvailableLocatorsException;
using apache::geode::client::NoSystemException;
using apache::geode::client::NotAuthorizedException;
using apache::geode::client::NotConnectedException;
using apache::geode::client::NotOwnerException;
using apache::geode::client::OutOfMemoryException;
using apache::geode::client::PutAllPartialResultException;
using apache::geode::client::QueryException;
using apache::geode::client::QueryExecutionLowMemoryException;
using apache::geode::client::RegionDestroyedException;
using apache::geode::client::RegionExistsException;
using apache::geode::client::RollbackException;
using apache::geode::client::StatisticsDisabledException;
using apache::geode::client::TimeoutException;
using apache::geode::client::TransactionDataNodeHasDepartedException;
using apache::geode::client::TransactionDataRebalancedException;
using apache::geode::client::UnknownException;

[[noreturn]] void notConnectedException(std::string message, std::string& exMsg,
                                        GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": not connected to Geode");
  throw NotConnectedException{message};
}

    [[noreturn]] void messageException(std::string message, std::string& exMsg,
                                       GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg
                                : ": message from server could not be handled");
  throw MessageException{message};
}

[[noreturn]] void cacheServerException(std::string message, std::string& exMsg,
                                       GfErrType err, std::string) {
  if (err == GF_CACHESERVER_EXCEPTION) {
    message.append(!exMsg.empty() ? exMsg
                                  : ": exception happened at cache server");
  }
  if (err == GF_CACHE_REGION_NOT_FOUND) {
    message.append(!exMsg.empty() ? exMsg : ": region not found on server");
  }

  throw CacheServerException{message};
}

    [[noreturn]] void notOwnerException(std::string message, std::string& exMsg,
                                        GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": not own the lock");
  throw NotOwnerException{message};
}

[[noreturn]] void illegalStateException(std::string message, std::string& exMsg,
                                        GfErrType err, std::string) {
  if (err == GF_CACHE_REGION_NOT_GLOBAL) {
    message.append(!exMsg.empty() ? exMsg : ": region not global");
  }
  if (err == GF_CACHE_ILLEGAL_STATE_EXCEPTION) {
    message.append(!exMsg.empty() ? exMsg : ": illegal State");
  }
  throw IllegalStateException{message};
}

    [[noreturn]] void illegalArgumentException(std::string message,
                                               std::string& exMsg,
                                               GfErrType err, std::string) {
  if (err == GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION) {
    message.append(!exMsg.empty() ? exMsg : ": illegal argument");
  }
  if (err == GF_CACHE_REGION_KEYS_NOT_STRINGS) {
    message.append(!exMsg.empty() ? exMsg
                                  : ": region entries do not support C access");
  }
  if (err == GF_CACHE_REGION_ENTRY_NOT_BYTES) {
    message.append(!exMsg.empty()
                       ? exMsg
                       : ": existing non-null values was not a byte array");
  }
  throw IllegalArgumentException{message};
}

[[noreturn]] void cacheWriterException(std::string message, std::string& exMsg,
                                       GfErrType err, std::string) {
  if (err == GF_CACHE_WRITER_EXCEPTION) {
    message.append(!exMsg.empty() ? exMsg
                                  : ": exception on server during write");
  }
  if (err == GF_CACHEWRITER_ERROR) {
    message.append(!exMsg.empty() ? exMsg : ": exception in CacheWriter");
  }
  throw CacheWriterException{message};
}

    [[noreturn]] void cacheLoaderException(std::string message,
                                           std::string& exMsg, GfErrType,
                                           std::string) {
  message.append(!exMsg.empty() ? exMsg : ": exception in CacheLoader");
  throw CacheLoaderException{message};
}

[[noreturn]] void cacheListenerException(std::string message,
                                         std::string& exMsg, GfErrType,
                                         std::string) {
  message.append(!exMsg.empty() ? exMsg : ": exception in CacheListener");
  throw CacheListenerException{message};
}

    [[noreturn]] void regionDestroyedException(std::string message,
                                               std::string& exMsg,
                                               GfErrType err, std::string) {
  if (err == GF_CACHE_REGION_INVALID) {
    message.append(!exMsg.empty() ? exMsg : ": region not valid");
  }
  if (err == GF_CACHE_REGION_DESTROYED_EXCEPTION) {
    message.append(!exMsg.empty() ? exMsg : ": Named Region Destroyed");
  }
  throw RegionDestroyedException{message};
}

[[noreturn]] void cacheProxyException(std::string message, std::string& exMsg,
                                      GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": error in Cache proxy");
  throw CacheProxyException{message};
}

    [[noreturn]] void geodeIOException(std::string message, std::string& exMsg,
                                       GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Input/Output error in operation");
  throw GeodeIOException{message};
}

[[noreturn]] void noSystemException(std::string message, std::string& exMsg,
                                    GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": entity does not exist");
  throw NoSystemException{message};
}

    [[noreturn]] void timeoutException(std::string message, std::string& exMsg,
                                       GfErrType err, std::string) {
  if (err == GF_CLIENT_WAIT_TIMEOUT) {
    message.append(!exMsg.empty()
                       ? exMsg
                       : ": timed out, possibly bucket is not available.");
  } else {
    message.append(!exMsg.empty() ? exMsg : ": timed out");
  }
  throw TimeoutException{message};
}

[[noreturn]] void outOfMemoryException(std::string message, std::string& exMsg,
                                       GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Out of memory");
  throw OutOfMemoryException{message};
}

    [[noreturn]] void bufferSizeExceededException(std::string message,
                                                  std::string& exMsg, GfErrType,
                                                  std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Buffer Size Exceeded");
  throw BufferSizeExceededException{message};
}

[[noreturn]] void leaseExpiredException(std::string message, std::string& exMsg,
                                        GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": lock Lease Expired On you");
  throw LeaseExpiredException{message};
}

    [[noreturn]] void regionExistsException(std::string message,
                                            std::string& exMsg, GfErrType,
                                            std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Named Region Exists");
  throw RegionExistsException{message};
}

[[noreturn]] void entryNotFoundException(std::string message,
                                         std::string& exMsg, GfErrType,
                                         std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Entry not found");
  throw EntryNotFoundException{message};
}

    [[noreturn]] void entryExistsException(std::string message,
                                           std::string& exMsg, GfErrType,
                                           std::string) {
  message.append(!exMsg.empty() ? exMsg
                                : ": Entry already exists in the region");
  throw EntryExistsException{message};
}

[[noreturn]] void entryDestroyedException(std::string message,
                                          std::string& exMsg, GfErrType,
                                          std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Entry has been destroyed");
  throw EntryDestroyedException{message};
}

    [[noreturn]] void cacheClosedException(std::string message,
                                           std::string& exMsg, GfErrType,
                                           std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Cache has been closed");
  throw CacheClosedException{message};
}

[[noreturn]] void statisticsDisabledException(std::string message,
                                              std::string& exMsg, GfErrType,
                                              std::string) {
  message.append(!exMsg.empty()
                     ? exMsg
                     : ": Statistics have been disabled for the region");
  throw StatisticsDisabledException{message};
}

    [[noreturn]] void concurrentModificationException(std::string message,
                                                      std::string& exMsg,
                                                      GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg
                                : ": Concurrent modification in the cache");
  throw ConcurrentModificationException{message};
}

[[noreturn]] void notAuthorizedException(std::string message,
                                         std::string& exMsg, GfErrType,
                                         std::string) {
  message.append(!exMsg.empty() ? exMsg : ": unauthorized operation");
  throw NotAuthorizedException{message};
}

    [[noreturn]] void authenticationFailedException(std::string message,
                                                    std::string& exMsg,
                                                    GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": authentication failed");
  throw AuthenticationFailedException{message};
}

[[noreturn]] void authenticationRequiredException(std::string message,
                                                  std::string& exMsg, GfErrType,
                                                  std::string) {
  message.append(!exMsg.empty() ? exMsg : ": no authentication provided");
  throw AuthenticationRequiredException{message};
}

    [[noreturn]] void duplicateDurableClientException(std::string message,
                                                      std::string& exMsg,
                                                      GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Duplicate Durable Client Id");
  throw DuplicateDurableClientException{message};
}

[[noreturn]] void queryException(std::string message, std::string& exMsg,
                                 GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Query failed");
  throw QueryException{message};
}

    [[noreturn]] void noAvailableLocatorsException(std::string,
                                                   std::string& exMsg,
                                                   GfErrType,
                                                   std::string func) {
  try {
    throw NoAvailableLocatorsException{
        func + (!exMsg.empty() ? exMsg : ": No locators available")};
  } catch (...) {
    std::throw_with_nested(NotConnectedException{
        func + (!exMsg.empty() ? exMsg : ": No locators available")});
  }
}

[[noreturn]] void allConnectionsInUseException(std::string message,
                                               std::string& exMsg, GfErrType,
                                               std::string) {
  message.append(!exMsg.empty() ? exMsg : ": All connections are in use");
  throw AllConnectionsInUseException{message};
}

    [[noreturn]] void functionExecutionException(std::string message,
                                                 std::string& exMsg, GfErrType,
                                                 std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Function execution failed");
  throw FunctionExecutionException{message};
}

[[noreturn]] void diskFailureException(std::string message, std::string& exMsg,
                                       GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Disk full");
  throw DiskFailureException{message};
}

    [[noreturn]] void rollbackException(std::string message, std::string& exMsg,
                                        GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Transaction rolled back");
  throw RollbackException{message};
}

[[noreturn]] void commitConflictException(std::string message,
                                          std::string& exMsg, GfErrType,
                                          std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Commit conflict exception");
  throw CommitConflictException{message};
}

    [[noreturn]] void transactionDataRebalancedException(std::string message,
                                                         std::string& exMsg,
                                                         GfErrType,
                                                         std::string) {
  message.append(!exMsg.empty() ? exMsg
                                : ": Transaction data rebalanced exception");
  throw TransactionDataRebalancedException{message};
}

[[noreturn]] void transactionDataNodeHasDepartedException(std::string message,
                                                          std::string& exMsg,
                                                          GfErrType,
                                                          std::string) {
  message.append(!exMsg.empty()
                     ? exMsg
                     : ": Transaction data node has departed exception");
  throw TransactionDataNodeHasDepartedException{message};
}

    [[noreturn]] void putAllPartialResultException(std::string message,
                                                   std::string& exMsg,
                                                   GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": PutAll Partial exception");
  throw PutAllPartialResultException{message};
}

[[noreturn]] void lowMemoryException(std::string message, std::string& exMsg,
                                     GfErrType, std::string) {
  message.append(!exMsg.empty() ? exMsg : ": Low memory exception");
  throw LowMemoryException{message};
}

    [[noreturn]] void queryLowMemoryException(std::string message,
                                              std::string& exMsg, GfErrType,
                                              std::string) {
  message.append(!exMsg.empty() ? exMsg
                                : ": Query execution low memory exception");
  throw QueryExecutionLowMemoryException{message};
}

[[noreturn]] void unknownException(std::string message, std::string& exMsg,
                                   GfErrType err, std::string func) {
  LOGINFO("error code: %d", err);
  message = func;
  if (exMsg.empty()) {
    message.append("Unknown error code ").append(std::to_string(err));
  } else {
    message.append(exMsg);
  }
  throw UnknownException{message};
}

}  // namespace

using error_function_t =
    std::function<void(std::string, std::string&, GfErrType, std::string)>;

std::map<GfErrType, error_function_t>& get_error_map() {
  static std::map<GfErrType, error_function_t> error_map{
      {GF_NOTCON, notConnectedException},
      {GF_MSG, messageException},
      {GF_CACHESERVER_EXCEPTION, cacheServerException},
      {GF_NOTOWN, notOwnerException},
      {GF_CACHE_REGION_NOT_FOUND, cacheServerException},
      {GF_CACHE_REGION_NOT_GLOBAL, illegalStateException},
      {GF_CACHE_ILLEGAL_ARGUMENT_EXCEPTION, illegalArgumentException},
      {GF_CACHE_ILLEGAL_STATE_EXCEPTION, illegalStateException},
      {GF_CACHE_WRITER_EXCEPTION, cacheWriterException},
      {GF_CACHEWRITER_ERROR, cacheWriterException},
      {GF_CACHE_LOADER_EXCEPTION, cacheLoaderException},
      {GF_CACHE_LISTENER_EXCEPTION, cacheListenerException},
      {GF_CACHE_REGION_INVALID, regionDestroyedException},
      {GF_CACHE_PROXY, cacheProxyException},
      {GF_IOERR, geodeIOException},
      {GF_ENOENT, noSystemException},
      {GF_CACHE_REGION_KEYS_NOT_STRINGS, illegalArgumentException},
      {GF_CACHE_REGION_ENTRY_NOT_BYTES, illegalArgumentException},
      {GF_CACHE_TIMEOUT_EXCEPTION, timeoutException},
      {GF_TIMEOUT, timeoutException},
      {GF_CLIENT_WAIT_TIMEOUT, timeoutException},
      {GF_ENOMEM, outOfMemoryException},
      {GF_ERANGE, bufferSizeExceededException},
      {GF_CACHE_LEASE_EXPIRED_EXCEPTION, leaseExpiredException},
      {GF_CACHE_REGION_EXISTS_EXCEPTION, regionExistsException},
      {GF_CACHE_ENTRY_NOT_FOUND, entryNotFoundException},
      {GF_CACHE_ENTRY_EXISTS, entryExistsException},
      {GF_CACHE_ENTRY_DESTROYED_EXCEPTION, entryDestroyedException},
      {GF_CACHE_REGION_DESTROYED_EXCEPTION, regionDestroyedException},
      {GF_CACHE_CLOSED_EXCEPTION, cacheClosedException},
      {GF_CACHE_STATISTICS_DISABLED_EXCEPTION, statisticsDisabledException},
      {GF_CACHE_CONCURRENT_MODIFICATION_EXCEPTION,
       concurrentModificationException},
      {GF_NOT_AUTHORIZED_EXCEPTION, notAuthorizedException},
      {GF_AUTHENTICATION_FAILED_EXCEPTION, authenticationFailedException},
      {GF_AUTHENTICATION_REQUIRED_EXCEPTION, authenticationRequiredException},
      {GF_DUPLICATE_DURABLE_CLIENT, duplicateDurableClientException},
      {GF_REMOTE_QUERY_EXCEPTION, queryException},
      {GF_CACHE_LOCATOR_EXCEPTION, noAvailableLocatorsException},
      {GF_ALL_CONNECTIONS_IN_USE_EXCEPTION, allConnectionsInUseException},
      {GF_FUNCTION_EXCEPTION, functionExecutionException},
      {GF_DISKFULL, diskFailureException},
      {GF_ROLLBACK_EXCEPTION, rollbackException},
      {GF_COMMIT_CONFLICT_EXCEPTION, commitConflictException},
      {GF_TRANSACTION_DATA_REBALANCED_EXCEPTION,
       transactionDataRebalancedException},
      {GF_TRANSACTION_DATA_NODE_HAS_DEPARTED_EXCEPTION,
       transactionDataNodeHasDepartedException},
      {GF_PUTALL_PARTIAL_RESULT_EXCEPTION, putAllPartialResultException},
      {GF_LOW_MEMORY_EXCEPTION, lowMemoryException},
      {GF_QUERY_EXECUTION_LOW_MEMORY_EXCEPTION, queryLowMemoryException},
      {GF_NOERR, unknownException},
      {GF_DEADLK, unknownException},
      {GF_EACCES, unknownException},
      {GF_ECONFL, unknownException},
      {GF_EINVAL, unknownException},
      {GF_ETYPE, unknownException},
      {GF_NOTOBJ, unknownException},
      {GF_NOTSUP, unknownException},
      {GF_SCPGBL, unknownException},
      {GF_SCPEXC, unknownException},
      {GF_OVRFLW, unknownException},
      {GF_EINTR, unknownException},
      {GF_NOSERVER_FOUND, unknownException},
      {GF_SERVER_FAILED, unknownException},
      {GF_CLIENT_WAIT_TIMEOUT_REFRESH_PRMETADATA, unknownException},
      {GF_CANNOT_PROCESS_GII_REQUEST, unknownException},
      {GF_CACHE_ENTRY_UPDATED, unknownException},
      {GF_INVALID_DELTA, unknownException},
      {GF_EUNDEF, unknownException}};

  return error_map;
}

namespace apache {
namespace geode {
namespace client {

void setThreadLocalExceptionMessage(std::string exMsg);
const std::string& getThreadLocalExceptionMessage();

[[noreturn]] void GfErrTypeThrowException(const char* str, GfErrType err) {
  std::string func;
  std::string message;
  auto exMsg = getThreadLocalExceptionMessage();
  setThreadLocalExceptionMessage("");
  if (!exMsg.empty()) {
    func.append(str);
    func.append(": ");
  }

  auto& error_map = get_error_map();
  auto iter = error_map.find(err);
  if (iter != std::end(error_map)) {
    iter->second(message, exMsg, err, func);
  }
  unknownException(message, exMsg, err, func);
}
}  // namespace client
}  // namespace geode
}  // namespace apache
