/*
 * 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 <geode/Cache.hpp>
#include <geode/CacheTransactionManager.hpp>

#include "TXState.hpp"
#include "TransactionalOperation.hpp"
#include "TssConnectionWrapper.hpp"
#include "ThinClientPoolDM.hpp"
#include "util/exception.hpp"

namespace apache {
namespace geode {
namespace client {

TXState::TXState(CacheImpl* cacheImpl) {
  m_txId = TXId();
  m_closed = false;
  m_modSerialNum = 0;
  m_dirty = false;
  m_replay = false;
  m_prepared = false;
  m_cache = cacheImpl;
  /* adongre
   * Non-static class member "m_suspendedExpiryTaskId" is not initialized in
   * this constructor nor in any functions that it calls.
   */
  m_suspendedExpiryTaskId = 0;
  m_pooldm = nullptr;
}

TXState::~TXState() {}
TXId& TXState::getTransactionId() { return m_txId; }

int32_t TXState::nextModSerialNum() {
  m_modSerialNum += 1;
  return m_modSerialNum;
}
std::shared_ptr<Cacheable> TXState::replay(bool isRollback) {
  GfErrTypeThrowException("Replay is unsupported", GF_NOTSUP);
  int retryAttempts = 3;

  std::shared_ptr<Cacheable> result = nullptr;

  ReplayControl replayControl(this);
  m_dirty = false;
  // if retryAttempts < 0 we retry until there are no servers available
  for (int i = 0; (retryAttempts < 0) || (i < retryAttempts); i++) {
    // try {
    if (isRollback) {  // need to roll back these
      try {
        m_cache->getCacheTransactionManager()
            ->rollback();  // this.firstProxy.rollback(proxy.getTxId().getUniqId());
      } catch (const Exception& ex) {
        LOGFINE(
            "caught exception when rolling back before retrying transaction "
            "%s",
            ex.what());
      }
    }
    m_txId = TXId();
    // LOGFINE("retrying transaction after loss of state in server.  Attempt #"
    // + (i+1));
    try {
      for (const auto& operation : m_operations) {
        result = operation->replay(m_cache);
      }

      return result;
    } catch (const TransactionDataNodeHasDepartedException& ex) {
      LOGDEBUG("Transaction exception:%s", ex.what());
      isRollback = false;
      // try again
    } catch (const TransactionDataRebalancedException& ex) {
      LOGDEBUG("Transaction exception:%s", ex.what());
      isRollback = true;
      // try again
    }
  }

  GfErrTypeThrowException(
      "Unable to reestablish transaction context on servers", GF_EUNDEF);

  return nullptr;
}

void TXState::releaseStickyConnection() {
  // Since this is called during cleanup or through destructor, we should not
  // throw exception from here,
  // which can cause undefined cleanup.
  TcrConnection* conn =
      (*TssConnectionWrapper::s_geodeTSSConn)->getConnection();
  if (conn != nullptr) {
    ThinClientPoolDM* dm = conn->getEndpointObject()->getPoolHADM();
    if (dm != nullptr) {
      if (!dm->isSticky()) {
        LOGFINE(
            "Release the sticky connection associated with the transaction");
        dm->releaseThreadLocalConnection();  // this will release connection now
      } else {
        LOGFINE(
            "Pool with sticky connection - don't Release the sticky connection "
            "associated with the transaction");
        conn->setAndGetBeingUsed(false, false);  // just release connection now
      }
    }
  }
}
}  // namespace client
}  // namespace geode
}  // namespace apache
