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